hdu 1272 判断所给的图是不是生成树 (并查集)
判断所给的图是不是生成树,如果有环就不是,如果没环但连通分量大于1也不是
find函数 用递归写的话 会无限栈溢出 Orz
要加上那一串 手动扩栈
Sample Input
6 8 5 3 5 2 6 4
5 6 0 0
8 1 7 3 6 2 8 9 7 5
7 4 7 8 7 6 0 0
3 8 6 8 6 4
5 3 5 6 5 2 0 0
-1 -1
Sample Output
Yes
Yes
No
1 # include <iostream> 2 # include <cstdio> 3 # include <cstring> 4 # include <algorithm> 5 # include <cmath> 6 # include <queue> 7 # define LL long long 8 #pragma comment(linker, "/STACK:1024000000,1024000000") 9 using namespace std ; 10 11 const int MAXN=100010; 12 int F[MAXN]; 13 bool vis[MAXN] ; 14 int save[MAXN] ; 15 bool flag ; 16 int find(int x)//找x的祖先结点 17 { 18 if(F[x]==x) return x; 19 return F[x]=find(F[x]); 20 } 21 void bing(int u,int v) 22 { 23 int t1=find(u); 24 int t2=find(v); 25 if(t1!=t2) F[t1]=t2; 26 else flag = 1 ; //有环 27 } 28 int main() 29 { 30 //freopen("in.txt","r",stdin) ; 31 int u , v ; 32 while(scanf("%d %d" , &u , &v) != EOF) 33 { 34 if (u == -1 && v == -1) 35 break ; 36 if (u == 0 && v == 0) 37 { 38 printf("Yes\n") ; 39 continue ; 40 } 41 int i ; 42 for(i=1;i<MAXN;i++) 43 { 44 F[i]=i; 45 } 46 memset(vis , 0 , sizeof(vis)) ; 47 F[u] = v ; 48 int l = 0 ; 49 flag = 0 ; 50 if (!vis[u]) 51 { 52 vis[u] = 1 ; 53 save[l++] = u ; 54 } 55 if (!vis[v]) 56 { 57 vis[v] = 1 ; 58 save[l++] = v ; 59 } 60 while(scanf("%d %d" , &u , &v)) 61 { 62 if (u == 0 && v == 0) 63 break ; 64 if (flag) 65 continue ; 66 if (!vis[u]) 67 { 68 vis[u] = 1 ; 69 save[l++] = u ; 70 } 71 if (!vis[v]) 72 { 73 vis[v] = 1 ; 74 save[l++] = v ; 75 } 76 bing(u,v) ; 77 } 78 int res = 0 ; //连通分量 79 for (i = 0 ; i < l ; i++) 80 if (F[save[i]] == save[i]) 81 res++ ; 82 if (res >= 2 || flag == 1) 83 printf("No\n") ; 84 else 85 printf("Yes\n") ; 86 } 87 return 0; 88 }