hdu 3172+hdu 3635+hdu 3926

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3172

思路:将名字转化为对应的序号就可以,然后就是基本的并查集操作了。。。

View Code
 1 #define _CRT_SECURE_NO_WARNINGS
 2 #include<iostream>
 3 #include<cstdio>
 4 #include<cstring>
 5 #include<map>
 6 #include<string>
 7 using namespace std;
 8 const int MAXN=100000+10;
 9 int parent[MAXN];
10 int n,num;
11 
12 int Find(int x){
13     int s;
14     for(s=x;parent[s]>=0;s=parent[s]);
15     while(s!=x){
16         int tmp=parent[x];
17         parent[x]=s;
18         x=tmp;
19     }
20     return s;
21 }
22 
23 void Union(int R1,int R2){
24     int r1=Find(R1);
25     int r2=Find(R2);
26     if(r1==r2)return ;
27     if(parent[r1]>parent[r2]){
28         parent[r1]+=parent[r2];
29         parent[r2]=r1;
30     }else {
31         parent[r2]+=parent[r1];
32         parent[r1]=r2;
33     }
34 }
35 
36 
37 
38 int main(){
39     int _case;
40     while(~scanf("%d",&_case)){
41         while(_case--){
42             scanf("%d",&n);
43             num=1;
44             map<string,int>mp;
45 
46             for(int i=1;i<=n;i++){
47                 char s1[22],s2[22];
48                 scanf("%s%s",s1,s2);
49                 if(mp.find(s1)==mp.end()){
50                     parent[num]=-1;
51                     mp[s1]=num++;
52                 }
53                 if(mp.find(s2)==mp.end()){
54                     parent[num]=-1;
55                     mp[s2]=num++;
56                 }
57                 Union(mp[s1],mp[s2]);
58                 int rt=Find(mp[s1]);
59                 printf("%d\n",abs(parent[rt]));
60             }
61         }
62     }
63     return 0;
64 }

 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3635

思路:这题的关键之处在于如何求出转移次数。。。其实我们可以在Find()函数中添加一个—_count[]数组来保存每次转移的次数,具体见代码:

View Code
 1 #define _CRT_SECURE_NO_WARNINGS
 2 #include<iostream>
 3 #include<cstdio>
 4 #include<cstring>
 5 using namespace std;
 6 const int MAXN=10000+10;
 7 int parent[MAXN];
 8 int _count[MAXN];
 9 int Rank[MAXN];
10 int n,m;
11 
12 void Initiate(){
13     for(int i=1;i<=n;i++){
14         parent[i]=i;
15         _count[i]=0;
16         Rank[i]=1;
17     }
18 }
19 
20 int Find(int x){
21     if(x==parent[x])return x;
22     else {
23         int tmp=parent[x];
24         parent[x]=Find(parent[x]);
25         _count[x]+=_count[tmp];//更新转移次数
26     }
27     return parent[x];
28 }
29 
30 
31 void Union(int R1,int R2){
32     int r1=Find(R1);
33     int r2=Find(R2);
34     if(r1==r2)return ;
35     else {
36         parent[r1]=r2;
37         _count[r1]++;
38         Rank[r2]+=Rank[r1];
39         Rank[r1]=0;
40     }
41 }
42 
43 
44 int main(){
45     int _case,t=1;
46     scanf("%d",&_case);
47     while(_case--){
48         scanf("%d%d",&n,&m);
49         Initiate();
50         printf("Case %d:\n",t++);
51         for(int i=1;i<=m;i++){
52             char str[11];
53             scanf("%s",str);
54             if(str[0]=='T'){
55                 int u,v;
56                 scanf("%d%d",&u,&v);
57                 Union(u,v);
58             }else if(str[0]=='Q'){
59                 int x;
60                 scanf("%d",&x);
61                 int y=Find(x);
62                 printf("%d %d %d\n",y,Rank[y],_count[x]);
63             }
64         }
65     }
66     return 0;
67 }

 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3926

思路:判断两个图是否同构:

首先当然是并查集的一些基本操作了,不过合并的时候应该遵循孩子节点少的合并到孩子节点多的集合中(不然wa),然后就是排序后比较一下就可以了(因为图可能存在环,因此可以先按孩子节点的个数排,然后再按是否存在环排);

View Code
  1 #define _CRT_SECURE_NO_WARNINGS
  2 #include<iostream>
  3 #include<cstdio>
  4 #include<cstring>
  5 #include<algorithm>
  6 using namespace std;
  7 const int MAXN=10000+10;
  8 int n1,m1,n2,m2;
  9 int parent1[MAXN],parent2[MAXN];
 10 struct Graph{
 11     int child;
 12     bool ring;//false代表成链,true代表成环
 13 };
 14 Graph g1[MAXN],g2[MAXN];
 15 
 16 void Initiate(){
 17     for(int i=1;i<=n1;i++){
 18         parent1[i]=-1;
 19         parent2[i]=-1;
 20         g1[i].child=1;
 21         g2[i].child=1;
 22         g1[i].ring=false;
 23         g2[i].ring=false;
 24     }
 25 }
 26 
 27 int Find(int x,int parent[]){
 28     int s;
 29     for(s=x;parent[s]>=0;s=parent[s]);
 30     while(s!=x){
 31         int tmp=parent[x];
 32         parent[x]=s;
 33         x=tmp;
 34     }
 35     return s;
 36 }
 37 
 38         
 39 
 40 void Union(int R1,int R2,int parent[],Graph g[]){
 41     int r1=Find(R1,parent);
 42     int r2=Find(R2,parent);
 43     if(r1==r2){
 44         g[r1].ring=true;//根结点相同,说明存在环
 45     }else {
 46         if(g[r1].child>=g[r2].child){
 47             parent[r2]=r1;
 48             g[r1].child+=g[r2].child;
 49         }else {
 50             parent[r1]=r2;
 51             g[r2].child+=g[r1].child;
 52         }
 53     }
 54 }
 55 
 56 int cmp(const Graph &g1,const Graph &g2){
 57     if(g1.child!=g2.child){
 58         return g1.child<g2.child;
 59     }
 60     return g1.ring<g2.ring;//先链后环
 61 }
 62 
 63 bool Solve(){
 64     sort(g1+1,g1+n1+1,cmp);
 65     sort(g2+1,g2+n2+1,cmp);
 66     for(int i=1;i<=n1;i++){
 67         if(g1[i].child!=g2[i].child||(g1[i].child==g2[i].child&&g1[i].ring!=g2[i].ring))
 68             return false;
 69     }
 70     return true;
 71 }
 72 
 73 
 74 
 75 int main(){
 76     int _case,t=1;
 77     scanf("%d",&_case);
 78     while(_case--){
 79         scanf("%d%d",&n1,&m1);
 80         Initiate();
 81         bool flag=true;
 82         for(int i=1;i<=m1;i++){
 83             int u,v;
 84             scanf("%d%d",&u,&v);
 85             Union(u,v,parent1,g1);
 86         }
 87         scanf("%d%d",&n2,&m2);
 88         if(m1!=m2||n1!=n2){
 89             flag=false;
 90         }
 91         for(int i=1;i<=m2;i++){
 92             int u,v;
 93             scanf("%d%d",&u,&v);
 94             if(!flag)continue;
 95             Union(u,v,parent2,g2);
 96         }
 97         printf("Case #%d: ",t++);
 98         if(!flag){
 99             printf("NO\n");
100         }else {
101             flag=Solve();
102             if(flag){
103                 printf("YES\n");
104             }else 
105                 printf("NO\n");
106         }
107     }
108     return 0;
109 }
110 
111             

 

posted @ 2013-04-20 10:50  ihge2k  阅读(420)  评论(0编辑  收藏  举报