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             

 

你可能感兴趣的:(HDU)