检查无向图的连通以及是否存在环
J - 小希的迷宫 HDU - 1272
1 #include <iostream> 2 #include <cstring> 3 #include <queue> 4 #include <set> 5 using namespace std; 6 const int maxn=1e5+5; 7 8 int x; 9 int f[maxn]; 10 int find(int x){ 11 if(x!=f[x]){ 12 f[x]=find(f[x]); 13 } 14 return f[x]; 15 } 16 void init(){ 17 for(int i=0;i<=100000;i++) 18 f[i]=i; 19 } 20 set<int> S; 21 int main(){ 22 int a,b;int flag=1; 23 std::ios::sync_with_stdio(false); 24 init(); 25 while(cin>>a>>b){ 26 if(a==-1&&b==-1) break; 27 if(a==0&&b==0) 28 { 29 //cout <<"flag="<<flag<<endl; 30 //cout <<"S.ize"<<S.size()<<endl; 31 if(flag==0) 32 { 33 cout <<"No\n"; 34 flag=1; 35 continue; 36 } 37 else 38 { 39 //cout <<"in"; 40 int sign;set<int>::iterator it=S.begin(); 41 if(!S.empty()) sign=find(*it),it++; 42 for(;it!=S.end();it++){ 43 if(find(*it)!=sign) flag=0; 44 //cout <<"in"; 45 } 46 if(flag) cout <<"Yes\n"; 47 else cout <<"No\n"; 48 } 49 //cout <<"in"; 50 flag=1; 51 S.clear(); 52 init(); 53 } 54 else 55 { 56 S.insert(a);S.insert(b); 57 int fa=find(a); 58 int fb=find(b); 59 //cout <<"root"<<fa<<" "<<fb<<endl; 60 if(fa==fb) 61 { 62 flag=0; 63 }else 64 { 65 f[fb]=fa; 66 } 67 } 68 } 69 70 return 0; 71 }
因为分到了并查集专题,就直接想到用并查集。
如果要连的当前边的两个端点在之前的图中已经连通,那么当前边一定会与之前的图构成一个环,那么直接就不成立了。如果没有环,那么再判断是否连通,如果连通就成立。算是一道并查集的应用题。