这个并查集又是个一个很模板的数据结构一个查找函数,一个合并函数,然后为了减小树的深度,需要压缩路径,这里推荐一个博客,我觉得写得特别详细;之后有时间要把二分路径压缩好好学一学;压缩路径也是优化算法的很重要的途径,然后做的时候我去查了一些资料,然后整理了一下思路,环,森林是不可以的,0 0 是树 然后自己指向自己也是不可以的;我在做的时候也没有仔细想过数组赋值的事情,所以第一次就wa了。
http://blog.csdn.net/youngyangyang04/article/details/7453564
#include<iostream> #include<cstdio> #include<cstring> #include<set> using namespace std; const int maxn=200; bool fa[maxn]; int jihe[maxn]; void makeset(void) { for(int i=1;i<105;i++) jihe[i]=i; } int find(int x) { return jihe[x] == x ? x : (jihe[x] = find(jihe[x])); } void join(int x,int y) { int fx=find(x),fy=find(y); if(fx==fy) return; jihe[fy]=fx; } int main() { int a,b,c,d;c=1; while(scanf("%d%d",&a,&b)!=EOF) { if(a==-1&&b==-1) break; if(a==0&&b==0) { printf("Case %d is a tree. ",c++); continue; } makeset(); memset(fa,false,sizeof(fa)); fa[a]=fa[b]; d=b; bool tree=true; if(a==b) tree=false; else join(a,b); while(scanf("%d%d",&a,&b)&&a!=0&&b!=0) { fa[a]=fa[b]=true; if(find(a)==find(b)) tree=false; join (a,b); } for(int i=1;i<100;i++) { if(fa[i]&&find(jihe[i])!=find(jihe[d])) tree=false; } if(tree) printf("Case %d is a tree. ",c++); else printf("Case %d is not a tree. ",c++); } return 0; }