zoukankan      html  css  js  c++  java
  • C

    Example
    input
     
    7 5
    3 2 5 4
    0
    2 1 2
    1 1
    2 6 7
    output
     
    4 4 1 4 4 2 2 


    思路:简单来讲,就是用并查集求每个点所在连通块的大小,有两种写法......


    写法一:用并查集合并所给边之后,再扫一遍标记每个联通块大小,最后输出,这个写法比较好理解,但是复杂度略高......


     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define ll long long
     4 #define quick ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
     5 const int inf=99999999;
     6 const int mod=1e9+7;
     7 const int maxn=5e5+5;
     8 int book[maxn];
     9 int f[maxn];
    10 void init(int n)
    11 {
    12     for(int i=0;i<=n+1;i++)
    13         f[i]=i;
    14 }
    15 int getf(int v)
    16 {
    17     if(f[v]==v)
    18         return v;
    19     else
    20     {
    21         f[v]=getf(f[v]);
    22         return f[v];
    23     }
    24 }
    25 void merge(int u,int v)
    26 {
    27     int t1=getf(u);
    28     int t2=getf(v);
    29     if(t1!=t2)
    30         f[t2]=t1;
    31 }
    32 int main()
    33 {
    34     quick;
    35     int n,m;
    36     cin>>n>>m;
    37     for(int i=0;i<=n;i++)
    38         f[i]=i;
    39     int k;
    40     int temp,num;
    41     for(int i=0;i<m;i++)
    42     {
    43         cin>>k;
    44         if(!k)
    45             continue;
    46         cin>>temp;
    47         k--;
    48         for(int i=0;i<k;i++)
    49         {
    50             cin>>num;
    51             merge(temp,num);
    52         }
    53     }
    54     for(int i=1;i<=n;i++)
    55         book[f[i]=getf(f[i])]++;
    56     for(int i=1;i<n;i++)
    57         cout<<book[f[i]]<<" ";
    58     cout<<book[f[n]];
    59     return 0;
    60 }
    
    
    

    写法二:用个size数组记录每个联通块大小,随并查集边合并的时候刷新,最后直接输出......



     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define ll long long
     4 #define quick ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
     5 const int inf=99999999;
     6 const int mod=1e9+7;
     7 const int maxn=5e5+5;
     8 int f[maxn];
     9 int size[maxn];
    10 void init(int n)
    11 {
    12     for(int i=1;i<=n+1;i++)
    13     {
    14         f[i]=i;
    15         size[i]=1;
    16     }
    17 }
    18 int getf(int v)
    19 {
    20     if(f[v]==v)
    21         return v;
    22     else
    23     {
    24         f[v]=getf(f[v]);
    25         return f[v];
    26     }
    27 }
    28 void merge(int u,int v)
    29 {
    30     u=getf(u);
    31     v=getf(v);
    32     if(u==v)
    33         return ;
    34     if(size[u]<size[v])
    35         swap(u,v);//让u所在联通块变成大的 
    36     f[v]=u;
    37     size[u]+=size[v];//将v的连通块合并到u上 
    38 }
    39 int main()
    40 {
    41     quick;
    42     int n,m;
    43     cin>>n>>m;
    44     init(n);
    45     int k;
    46     int temp,num;
    47     for(int i=0;i<m;i++)
    48     {
    49         cin>>k;
    50         if(!k)
    51             continue;
    52         cin>>temp;
    53         k--;
    54         for(int i=0;i<k;i++)
    55         {
    56             cin>>num;
    57             merge(temp,num);
    58         }
    59     }
    60     for(int i=1;i<n;i++)
    61         cout<<size[getf(i)]<<" ";
    62     cout<<size[getf(n)];
    63     return 0;
    64 }
    
    


    大佬见笑,,
  • 相关阅读:
    看大话设计模式读书笔记
    Android 混淆之proguard
    新手理解Navigator的教程
    Content Provider的权限
    INSTALL_PARSE_FAILED_MANIFEST_MALFORMED
    Android HOME键那些事
    SwipeRefreshLayout 源码分析
    Android Bander设计与实现
    Android Studio 调试技巧
    SSDP 简单服务发现协议
  • 原文地址:https://www.cnblogs.com/xwl3109377858/p/10890580.html
Copyright © 2011-2022 走看看