您的位置:首页 > 其它

bzoj 1529

2016-04-07 18:42 375 查看


【bzoj1529】[POI2005]ska Piggy banks

2014年5月17日8550


Description

Byteazar 有 N 个小猪存钱罐. 每个存钱罐只能用钥匙打开或者砸开. Byteazar 已经把每个存钱罐的钥匙放到了某些存钱罐里. Byteazar 现在想买一台汽车于是要把所有的钱都取出来. 他想尽量少的打破存钱罐取出所有的钱,问最少要打破多少个存钱罐.


Input

第一行一个整数 N (1 <= N <= 1.000.000) – 表示存钱罐的总数. 接下来每行一个整数,第 i+1行的整数代表第i个存钱罐的钥匙放置的存钱罐编号.


Output

一个整数表示最少打破多少个存钱罐.


Sample Input

4

2

1

2

4


Sample Output

2

In the foregoing example piggy banks 1 and 4 have to be smashed.

解题思路:原本想用tarjan来做,看到黄学长说超空间。又看到并查集的做法,神奇啊。。。

好像最小点基可以用并查集来求。

#include<cstdio>

#include<cstring>

#include<iostream>

#include<algorithm>

using namespace std;

int n;

int f[1000001];

inline int read()

{

char y; int x=0,f=1; y=getchar();

while (y<'0' || y>'9') {if (y=='-')f=-1; y=getchar();}

while (y>='0' && y<='9') {x=x*10+int(y)-48; y=getchar();}

return x*f;

}

int find(int o)

{

if (f[o]!=o) f[o]=find(f[o]);

return f[o];

}

int main()

{

n=read();

for (int i=1;i<=n;++i)

f[i]=i;

for (int i=1;i<=n;++i)

{

int u=read();

int x1=find(u); int x2=find(i);

if (x1!=x2)

{

f[x1]=x2;

}

}

int ans=0;

for (int i=1;i<=n;++i)

if (find(i)==i)

ans+=1;

printf("%d",ans);

}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: