标签:并查集 continue insert 压缩 -- class ora view 不同
tips:
1.并查集产生的每一个集合都是一棵树。
2.流程:初始化;查找--判断两个元素是否在一个集合;合并。
3.查找过程递归会爆栈(本题),可以用非递归的方法进行路径压缩。
4.用并查集判断是否有环:对同一个集合来说只存在一个根节点,且将其作为所属集合的标识。
5.合并的过程是一个建树的过程。当合并失败时,说明两个节点在同一个集合中,这两点连的边成环。
6.用isroot数组记录有几个根节点--有几个不同的集合。
7.此题原算法应该可行----待填。
//题解参考:https://blog.csdn.net/su20145104009/article/details/46981341 //判断是否有环并查集 //判断是否连通---一棵树---顶点数==边数+1//我原来的算法是记录下根的个数也行吧o(╥﹏╥)o #include<bits/stdc++.h> using namespace std; const int M=1e5+10; int father[M]; bool circle; void init(){ for(int i=1;i<=M;i++){ father[i]=i; } } int finddad(int x){ while(x != father[x]){ x=father[x]; } return father[x]; } void unionn(int x,int y){ int fx=finddad(x); int fy=finddad(y); if(fx != fy) { father[fx]=fy; } else circle=0; } int main(){ set<int >s; int a,b,sum; while(scanf("%d%d",&a,&b)!=EOF){ init(); sum=1,circle=false; if(a== 0 && b== 0) { printf("Yes\n"); continue; } if(a== -1 && b==-1 ) break; s.insert(a); s.insert(b); if(!circle){ unionn(a,b); } while(1){ scanf("%d%d",&a,&b); if(a==0 && b== 0) break; s.insert(a);s.insert(b); if(!circle) unionn(a,b); sum++; } if(!circle && s.size()== sum+1) printf("Yes\n"); else printf("No\n"); s.clear(); } return 0; }
标签:并查集 continue insert 压缩 -- class ora view 不同
原文地址:https://www.cnblogs.com/SUMaywlx/p/9403470.html