杭电1272AND北大1308

小希的迷宫

View Code
 1 //杭电1272
 2 #include <stdio.h>
 3 #include <string.h>
 4 
 5 #define N 100005
 6 int father[N],leftt[N],rightt[N];
 7 int find(int x)
 8 {
 9   if(father[x]==-1)
10       return x;
11   else
12       return find(father[x]);
13 }
14 void unionset(int x,int y)
15 {
16   father[y]=x;
17 }
18 int main()
19 {
20   int a,b;
21   while(scanf("%d%d",&a,&b))
22   {
23     memset(leftt,-1,sizeof(leftt));
24     memset(rightt,-1,sizeof(rightt));
25     memset(father,-1,sizeof(father));
26     if(a==-1&&b==-1)
27         break;
28     if(a==0&&b==0)
29         {printf("Yes\n");continue;}
30     int i=0;
31     leftt[i]=a;rightt[i]=b;
32     while(scanf("%d%d",&a,&b)&&a&&b){
33       i++;
34       leftt[i]=a;rightt[i]=b;
35     }
36     int flag=1;
37     for(int j=0;j<=i;++j)
38     {
39       int p=find(leftt[j]);
40       int q=find(rightt[j]);
41       if(rightt[j]!=find(rightt[j])||p==q)
42       {
43        flag=0;break;
44       }
45       
46         if(p!=q)
47           unionset(p,q);
48      }
49     if(flag==0)
50         printf("No\n");
51     else
52     {
53         int xx=find(rightt[0]),t;
54         for(t=1;t<=i&&xx==find(rightt[t]);++t);
55         if(t>i)
56         printf("Yes\n");
57         else
58             printf("No\n");
59     }
60   }
61   return 0;
62 }
View Code
 1 //北大poj1308
 2 
 3 #include<stdio.h>
 4 #include<string.h>
 5 #define N 100005
 6 int a[N],b[N],set[N];
 7 int find(int x)//find函数来查找根结点
 8 {
 9 
10     if(set[x]==-1)
11         return x;
12     else
13         return find(set[x]);//路径压缩,使其递归回来的路径元素都指向其根结点
14 }
15 void power(int x,int y)
16 {
17     set[y]=x;//当两个元素属于同一个集合时,把其合并为同一个集合
18 }
19 int main()
20 {
21     int m,n,i,j,t,l,x,y,f,k;
22     k=0;
23     while(scanf("%d%d",&m,&n))
24     {
25         k++;//用来记忆实例个数
26         memset(a,-1,sizeof(a));
27         memset(b,-1,sizeof(b));
28         memset(set,-1,sizeof(set));//将其根结点全部置为-1
29         if(m==-1&&n==-1)
30             break;
31         if(m==0&&n==0)
32         {
33             printf("Case %d is a tree.\n",k);
34             continue;
35         }
36         i=0;
37         a[i]=m;b[i]=n;
38         while(scanf("%d%d",&m,&n)&&m&&n)
39         {
40             i++;
41             a[i]=m;b[i]=n;//将其每组元素对应存入数组,为下一步更为方便的判断根结点
42         }
43         f=1;
44         for(j=0;j<=i;j++)
45         {
46             x=find(a[j]);
47             y=find(b[j]);
48             if(x==y||b[j]!=y)
49             {
50                 f=0;
51                 break;
52             }
53             else
54             {
55                 if(x!=y)
56                     power(x,y);
57             }
58         }
59         if(f==0)
60 
61             printf("Case %d is not a tree.\n",k);
62             
63 
64         else
65         {
66             l=find(b[0]);
67         
68             for(t=1;t<=i&&l==find(b[t]);++t);
69             if(i<t)
70                 printf("Case %d is a tree.\n",k);
71             else
72                 printf("Case %d is not a tree.\n",k);
73         }
74     }
75     return 0;
76 }
77                 

本道题主要运用查并集,主要难点在于如何对无序的元素集合关系进行根结点判断。代码从网上找的,到现在也不是很明白。

原文地址:https://www.cnblogs.com/zlyblog/p/2594135.html