• 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             
  • 相关阅读:
    Redis 思维导图 (解析版)
    一张图片了解redis
    Redis 思维导图
    计算机网络协议
    IT笔面试题
    Hadoop集群搭建
    天涯论坛只看楼主
    齐秦&r大约在冬季现场版
    郁可唯茶汤现场版
    MTK平台电路设计01
  • 原文地址:https://www.cnblogs.com/wally/p/3031628.html
Copyright © 2020-2023  润新知