zoukankan      html  css  js  c++  java
  • hdu 并查集专题

    http://acm.hdu.edu.cn/diy/contest_show.php?cid=16562

    1.How Many Tables

    View Code
     1 #include<stdio.h>
     2 int root[1001];
     3 int find(int x)
     4 {
     5     int r=x;
     6     while(r!=root[r])
     7     r=root[r];
     8     int i=x,j;
     9     /*
    10     while(i!=r)
    11     {
    12         j=root[i];
    13         root[i]=r;
    14         i=j;
    15     }
    16     */
    17     return r;
    18     
    19 }
    20 
    21 void merge(int x,int y)
    22 {
    23     
    24     int fx,fy;
    25     fx=find(x);
    26     fy=find(y);
    27     if(fx!=fy) root[fx]=fy; 
    28 }
    29 int main()
    30 {
    31     int t;
    32     int n,m;
    33     int i,j;
    34     int a,b;
    35     scanf("%d",&t);
    36     while(t--)
    37     {
    38         scanf("%d%d",&n,&m);
    39         for(i=1;i<=n;i++)
    40         root[i]=i;
    41         for(i=0;i<m;i++)
    42         {
    43             scanf("%d%d",&a,&b);
    44             merge(a,b);
    45         }
    46         int count=0;
    47         for(i=1;i<=n;i++)
    48         {
    49             if(find(i)==i)
    50             {
    51                 count++;
    52                 
    53             }
    54         }
    55         printf("%d\n",count);
    56     }
    57 }

     2.小希的迷宫

    View Code
     1 #include<stdio.h>
     2 int root[100010];
     3 int vis[100010];
     4 int find(int x)
     5 {
     6     while(x!=root[x])
     7     x=root[x];
     8     return x;
     9 }
    10 void merge(int x,int y)
    11 {
    12     
    13     int fx,fy;
    14     fx=find(x);
    15     fy=find(y);
    16     if(fx!=fy) root[fx]=fy;
    17 }
    18 void init()
    19 {
    20     for(int i=1;i<=100000;i++)
    21     {
    22         root[i]=i;
    23         vis[i]=0;
    24     }
    25 }
    26 int main()
    27 {
    28     int flag=0;
    29     int a,b;
    30     
    31     while(~scanf("%d%d",&a,&b))
    32     {
    33         int jie=0;
    34         init();
    35         if(a==-1&&b==-1) break;
    36         if(a==0&&b==0) 
    37         {
    38             printf("Yes\n");
    39             continue;
    40         }
    41         if(vis[a]==0)
    42         {
    43             jie++;
    44             vis[a]=1;
    45         }
    46         if(vis[b]==0)
    47         {
    48             jie++;
    49             vis[b]=1;
    50         }
    51         merge(a,b);
    52         jie--;
    53         while(~scanf("%d%d",&a,&b))
    54         {
    55             if(a==0&&b==0) break;
    56             if(find(a)==find(b))
    57             {
    58                 flag=1;
    59                 //break;
    60             }
    61             else 
    62             {
    63                 if(vis[a]==0)
    64                 {
    65                     vis[a]=1;
    66                     jie++;
    67                 }
    68                 if(vis[b]==0)
    69                 {
    70                     vis[b]=1;
    71                     jie++;
    72                 }
    73                 merge(a,b);
    74                 jie--;
    75             }
    76         }
    77         
    78         if(flag==0&&jie==1) printf("Yes\n"); 
    79         else printf("No\n");
    80         
    81     }
    82 }

    前面那写错了,flag应该在里面,竟然过了,数据弱爆了。 

    3.Is It A Tree?

     不能有两个父节点

    View Code
     1 /*
     2 看了别人写的,交了好多次
     3 1.a,b为负数退出,而不是-1,-1
     4 2.a,b有一个0是树 
     5 */ 
     6 
     7 #include<stdio.h>
     8 #include<string.h>
     9 int root[100010];
    10 int vis[100010];
    11 int main()
    12 {
    13     
    14     int a,b;
    15     int k=1;
    16     int flag;
    17     int jie,jie2;
    18     while(~scanf("%d%d",&a,&b))
    19     {
    20         memset(root,0,sizeof(root));
    21         memset(vis,0,sizeof(vis));
    22         flag=0;
    23         jie=0;
    24         jie2=0;
    25         if(a<0&&b<0) break;
    26         if(a==0||b==0) 
    27         {
    28             printf("Case %d is a tree.\n",k);
    29             k++;
    30             continue;
    31         }
    32         if(vis[a]==0)
    33         {
    34             jie++;
    35             vis[a]=1;
    36         }
    37         if(vis[b]==0)
    38         {
    39             jie++;
    40             vis[b]=1;
    41         }
    42         if(root[b]==0)
    43         {
    44             root[b]==1;
    45             jie2++;
    46         }
    47         else
    48         flag=1;
    49         while(~scanf("%d%d",&a,&b))
    50         {
    51             
    52             if(a==0&&b==0) break;
    53             if(root[b]==0)
    54             {
    55                 root[b]=1;
    56                 jie2++;
    57             }
    58             else flag=1;
    59                 if(vis[a]==0)
    60                 {
    61                     vis[a]=1;
    62                     jie++;
    63                 }
    64                 if(vis[b]==0)
    65                 {
    66                     vis[b]=1;
    67                     jie++;
    68                 }
    69             }
    70         if(!jie&&!jie2) printf("Case %d is a tree.\n",k); 
    71         if(flag||jie-jie2!=1) printf("Case %d is not a tree.\n",k); 
    72         else printf("Case %d is a tree.\n",k);
    73         k++;
    74         
    75     }
    76 }

     4.More is better

    View Code
     1 #include<stdio.h>
     2 #define Max(x,y) x>y?x:y
     3 int root[10000010];
     4 int vis[10000010];
     5 int find(int x)
     6 {
     7     int r=x;
     8     while(r!=root[r])
     9     r=root[r];
    10     int i=x,j;
    11     while(i!=r)
    12     {
    13         j=root[i];
    14         root[i]=r;
    15         i=j;
    16     }
    17     return r;
    18 } 
    19 void init()
    20 {
    21     int i;
    22     for(i=1;i<=10000000;i++)
    23     {
    24         root[i]=i;
    25     vis[i]=1;
    26     }
    27 }
    28 
    29 void merge(int x,int y)
    30 {
    31     int fx,fy;
    32     fx=find(x);
    33     fy=find(y);
    34     if(fx>fy) 
    35     {
    36         root[fx]=fy;
    37         vis[fy]+=vis[fx];
    38     }
    39     else if(fy>fx)//注意 else if(fy>fx)而不是else ,输入同一个数是同一个人 
    40     {
    41         root[fy]=fx;
    42         vis[fx]+=vis[fy];
    43     }
    44 }
    45 
    46 int main()
    47 {
    48     int n;
    49     int i;
    50     int a,b;
    51     while(~scanf("%d",&n))
    52     {
    53         init();
    54         for(i=1;i<=n;i++)
    55         {
    56             scanf("%d%d",&a,&b);
    57             merge(a,b);
    58         }
    59         int max=vis[1];
    60         for(i=1;i<=10000000;i++)//不要求点的个数,因为没说按顺序 
    61         {
    62             max=Max(max,vis[i]);
    63         }
    64         printf("%d\n",max);
    65     }
    66     
    67 }

    6.畅通工程

    View Code
     1  #include<stdio.h>
     2  #include<string.h>
     3  #include<stdlib.h>
     4  int  root[105];
     5  struct Node
     6  {
     7      int u;
     8      int v;
     9      int len;
    10  }node[105];
    11  int cmp(const void *a,const void *b)
    12  {
    13      return (*(Node*)a).len>(*(Node*)b).len?1:-1;//结构体按len从小到大排序 
    14  }
    15  int find(int x)
    16  {
    17      int r=x;
    18      while(r!=root[r])
    19      {
    20          r=root[r];
    21      }
    22      
    23      int i=x;
    24      int j;
    25      while(i!=r)
    26      {
    27          j=root[i];
    28          root[i]=r;
    29          i=j;
    30     }
    31     
    32      return r;
    33 }
    34  
    35  void merge(int x,int y)
    36  {
    37      
    38      
    39      int fx,fy;
    40      fx=find(x);
    41      fy=find(y);
    42      if(fx!=fy) root[fx]=fy;
    43  }
    44  
    45  
    46  
    47  int main()
    48  {
    49      int n,m;
    50      int i,j,k;
    51      
    52      while(~scanf("%d%d",&n,&m),n)
    53      {
    54          for(i=1;i<=m;i++)
    55          root[i]=i;
    56          int sum=0;
    57          for(i=0;i<n;i++)
    58          {
    59              scanf("%d%d%d",&node[i].u,&node[i].v,&node[i].len);
    60              
    61          }
    62          
    63          qsort(node,n,sizeof(node[0]),cmp);
    64          
    65          for(i=0;i<n;i++)
    66          {
    67              if(find(node[i].u)!=find(node[i].v))
    68              {
    69                  merge(node[i].u,node[i].v);
    70              sum+=node[i].len;
    71              }
    72          }
    73          int count=0;
    74          for(i=1;i<=m;i++)
    75          root[i]=find(i);
    76          for(i=1;i<=m;i++)
    77          {
    78              if(root[i]==i)
    79              count++;
    80          }
    81          if(count>1) printf("?\n");
    82          else printf("%d\n",sum);
    83      }
    84      
    85      
    86  }

    7.继续畅通工程

    View Code
     1 #include<stdio.h>
     2 #include<stdlib.h>
     3 int root[105];
     4 struct Node
     5 {
     6     int start;
     7     int end;
     8     int  len;
     9     int state;
    10 }node[5000];
    11 int cmp(const void *a,const void *b)
    12 {
    13     return (*(Node*)a).len>(*(Node*)b).len?1:-1;
    14 }
    15 int find(int x)
    16 {
    17     int r=x;
    18     while(r!=root[r])
    19     r=root[r];
    20     return r;
    21 }
    22 void merge(int x,int y)
    23 {
    24     
    25     int fx,fy;
    26     fx=find(x);
    27     fy=find(y);
    28     if(fx!=fy) root[fx]=fy;
    29 }
    30 int main()
    31 {
    32     int n;
    33     int m;
    34     int i,j,k;
    35     while(~scanf("%d",&n),n)
    36     {
    37         for(i=1;i<=n;i++)
    38         root[i]=i;
    39         m=n*(n-1)/2;
    40         int sum=0;
    41         for(i=0;i<m;i++)
    42         {
    43             scanf("%d%d%d%d",&node[i].start,&node[i].end,&node[i].len,&node[i].state);
    44             if(node[i].state==1) 
    45             {
    46             merge(node[i].start,node[i].end);//这句话可以用node[i].len=0;换 
    47             
    48             }
    49             
    50         }
    51         qsort(node,m,sizeof(node[1]),cmp);
    52 
    53         for(i=0;i<m;i++)
    54         {
    55             if(find(node[i].start)!=find(node[i].end))
    56             {
    57                 merge(node[i].start,node[i].end);
    58                 sum+=node[i].len;
    59             }
    60         }
    61         
    62         printf("%d\n",sum);
    63     }
    64 }

    11.A Bug's life

    View Code
     1 #include<stdio.h>
     2 int root[2005];
     3 int vis[2005];
     4 int find(int x)
     5 {
     6     int r=x;
     7     while(r!=root[r])
     8     r=root[r];
     9     return r;
    10 }
    11 void merge(int x,int y)
    12 {
    13     
    14     int fx,fy;
    15     fx=find(x);
    16     fy=find(y);
    17     if(fx!=fy) root[fx]=fy;
    18     
    19 }
    20 
    21 int main() 
    22 {
    23     int n,m;
    24     int t,i;
    25     int a,b;
    26     int count=0;
    27     int flag;
    28     scanf("%d",&t);
    29     while(t--)
    30     {
    31         flag=0;
    32         scanf("%d%d",&n,&m);
    33         for(i=1;i<=n;i++)
    34         {
    35             root[i]=i;
    36             vis[i]=0;
    37         }
    38         count++;
    39         
    40             for(i=1;i<=m;i++)
    41             {
    42                 scanf("%d%d",&a,&b);
    43                 if(vis[a]==0) 
    44                 {
    45                     vis[a]=b;
    46                 }
    47                 else
    48                 {
    49                     merge(vis[a],b);
    50                 }
    51                 if(vis[b]==0) 
    52                 {
    53                     vis[b]=a;
    54                 }
    55                 else
    56                 {
    57                     merge(vis[b],a);
    58                 }
    59                 if(find(a)==find(b)) 
    60                 {
    61                     flag=1;
    62                 }
    63             
    64           }
    65           printf("Scenario #%d:\n",count);
    66           if(flag)  printf("Suspicious bugs found!\n");
    67           else printf("No suspicious bugs found!\n");
    68           printf("\n");
    69     }
    70 }
  • 相关阅读:
    uva 1606 极角扫描
    Codeforces Round #304 (Div. 2) 题解
    Codeforces Round #306 (Div. 2) 题解
    Codeforces Round #299 (Div. 2) 题解
    树链剖分专题
    bzoj 1036: [ZJOI2008]树的统计Count
    bzoj 1007: [HNOI2008]水平可见直线
    bzoj 1003: [ZJOI2006]物流运输trans
    Codeforces Round #301 (Div. 2) 题解
    bzoj 1026: [SCOI2009]windy数
  • 原文地址:https://www.cnblogs.com/1114250779boke/p/2633788.html
Copyright © 2011-2022 走看看