hdu1272 hdu1325 poj1308 并查集
好久没写题了,水一水练习一下吧:
hdu1272判断连通无环图:
判断成环的时候,只要判断输入边的两个点。
有一个共同的父节点,那么这两个点就成环。
判断连通的时候,只要判断根节点数为1即可。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <stdio.h> 2 #define N 100010 3 int father[N]; 4 int mark[N]; 5 int find(int x){ 6 if(x!=father[x]) 7 father[x]=find(father[x]); 8 return father[x]; 9 } 10 void merge(int a,int b){ 11 int x=find(a); 12 int y=find(b); 13 if(x!=y) father[x]=y; 14 } 15 int main(){ 16 int a,b; 17 while(scanf("%d%d",&a,&b)!=EOF){ 18 if(a==-1&&b==-1) break; 19 if(a==0&&b==0){ 20 puts("Yes"); 21 continue; 22 } 23 int flag=1; 24 for(int i=0;i<N;i++){ 25 father[i]=i; 26 mark[i]=0; 27 } 28 merge(a,b); 29 mark[a]=mark[b]=1; 30 while(scanf("%d%d",&a,&b)!=EOF){ 31 if(a==0&&b==0) break; 32 int x=find(a); 33 int y=find(b); 34 if(x==y) flag=0; 35 else merge(x,y); 36 mark[a]=mark[b]=1; 37 } 38 if(!flag) puts("No"); 39 else{ 40 for(int i=0;i<N;i++){ 41 if(mark[i]&&father[i]==i){ 42 flag++; 43 } 44 } 45 if(flag==2) puts("Yes"); 46 else puts("No"); 47 } 48 } 49 return 0; 50 }
hdu1325&&poj1308判断是不是一棵树,hdu至今仍WA,poj上AC
看一幅图是不是一颗树
1. 肯定满足只有一个树根,只有一个入度为0的点。
2. 除了根每个点的入度只能为1
3. 无环
4. n个点只能有n-1个边
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <stdio.h> 2 #define N 10010 3 int father[N],vis[N]; 4 int find(int x){ 5 if(x!=father[x]) 6 father[x]=find(father[x]); 7 return father[x]; 8 } 9 void merge(int a,int b){ 10 if(a<b) father[a]=b; 11 else father[b]=a; 12 } 13 int main(){ 14 int n,m,k=1,flag,max=-1,fa,fb; 15 while(scanf("%d%d",&n,&m)){ 16 if(n==-1&&m==-1) return 0; 17 if(n==0&&m==0){ 18 printf("Case %d is a tree.\n",k++); 19 continue; 20 } 21 flag=0; 22 for(int i=1;i<=N;i++){ 23 father[i]=i; 24 vis[i]=0; 25 } 26 if(n>max) max=n; 27 if(m>max) max=m; 28 vis[n]=vis[m]=1; 29 fa=find(n); 30 fb=find(m); 31 if(fa==fb) flag++; 32 else merge(fa,fb); 33 while(scanf("%d%d",&n,&m)){ 34 if(n==0&&m==0) break; 35 if(n>max) max=n; 36 if(m>max) max=m; 37 vis[n]=vis[m]=1; 38 fa=find(n); 39 fb=find(m); 40 if(fa==fb) flag++; 41 else merge(fa,fb); 42 } 43 for(int i=1;i<=max;i++){ 44 if(vis[i]&&father[i]==i) 45 flag++; 46 } 47 if(flag==1) printf("Case %d is a tree.\n",k++); 48 else printf("Case %d is not a tree.\n",k++); 49 } 50 return 0; 51 }
一开始把find函数写错了,AC了1272,但是poj1308一直RE,
写成了
int find(int x){
if(x!=father[x])
return father[x]=find(father[x]);
} //死循环了
正确的应该是:
int find(int x){
if(x!=father[x])
father[x]=find(father[x]);
return father[x];
}