题目大意:有n个储钱罐,每个的钥匙都在另一个里面,求取出所有储钱罐中的钱最少要砸开几个
容易发现每个联通块都是一棵外向树,我们只需要砸开环上的任意一个节点就可以打开这个联通块中的所有储钱罐
问题转化成了求一个图的联通块个数 上并查集即可
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define M 1001001 using namespace std; int n,ans; namespace Union_Find_Set{ int fa[M]; int Find(int x) { if(!fa[x]||fa[x]==x) return fa[x]=x; return fa[x]=Find(fa[x]); } void Union(int x,int y) { x=Find(x);y=Find(y); if(x==y) return ; fa[x]=y; ans--; } } int main() { using namespace Union_Find_Set; int i,x; cin>>n;ans=n; for(i=1;i<=n;i++) { scanf("%d",&x); Union(x,i); } cout<<ans<<endl; return 0; }
BZOJ 1529 POI2005 ska Piggy banks 并查集
原文地址:http://blog.csdn.net/popoqqq/article/details/44830863