hdu1272 hdu1325 poj1308 并查集

好久没写题了,水一水练习一下吧:

hdu1272判断连通无环图:
  判断成环的时候,只要判断输入边的两个点。
  有一个共同的父节点,那么这两个点就成环。
  判断连通的时候,只要判断根节点数为1即可。

View Code
 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个边

View Code
 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];
}

posted @ 2013-01-08 14:53  _sunshine  阅读(802)  评论(0编辑  收藏  举报