ProblemC、小花梨判连通时间限制:2000ms 空间限制:512MBDescription小花梨给出?个点,让?位同学对这?个点任意添加无向边,构成?张图。小花梨想知道对于每个点?,存在多少个点?(包括?本身),使得?和?在这?张图中都是连通的。Input第一行输入两个正整数?和?,分别表示点的个数和同学数。接下来分成?部分进行输入,每部分输入格式相同。每部分第一行输入一个整数??,表示第?位同学连边的数目。接下来??行,每行两个正整数?,?,表示第?位同学将点?和点?之间进行连接。可能会存在重边或者自环。(1≤?≤100000,1≤?≤10,1≤?,?≤?,0≤??≤200000)Output输出?行,第?行输出在?张图中都和编号为?的点连通的点的数目(包括?本身)ExampleSample InputSample Output4231 21323212342211

在比赛时 并没有想出本题

知道需要进行几次搜索

但是

但是并没有想到用vector才作为每个点 来储存染色信息

标程

#include<bits/stdc++.h>
using namespace std;
const int MAXN=100005;
struct DSU
{
    int fa[MAXN];
    void init(int n)
    {
        for(int i=1;i<=n;i++)
            fa[i]=i;
    }
    int find(int x)
    {
        return fa[x]==x ? x : fa[x]=find(fa[x]);
    }
    void merge(int x,int y)
    {
        x=find(x),y=find(y);
        if(x!=y)fa[x]=y;
    }
}dsu;
vector<int> idx[MAXN];
map<vector<int>,vector<int> > mp;
int res[MAXN];
int main()
{
    int n,k;
    scanf("%d%d",&n,&k);
    for(int i=1;i<=k;i++)
    {
        dsu.init(n);
        int m;
        scanf("%d",&m);
        while(m--)
        {
            int u,v;
            scanf("%d%d",&u,&v);
            dsu.merge(u,v);
        }
        for(int i=1;i<=n;i++)
            idx[i].push_back(dsu.find(i));
    }
    for(int i=1;i<=n;i++)
        mp[idx[i]].push_back(i);
    for(auto &t:mp)
        for(auto &i:t.second)
            res[i]=t.second.size();
    for(int i=1;i<=n;i++)
        printf("%d\n",res[i]);
    return 0;
}
服务