题目链接:https://acm.ecnu.edu.cn/contest/173/problem/C/
题意:
Description 小花梨给出?个点,让?位同学对这?个点任意添加无向边,构成?张图。小花梨想知道对于 每个点?,存在多少个点?(包括?本身),使得?和?在这?张图中都是连通的。
Input 第一行输入两个正整数?和?,分别表示点的个数和同学数。 接下来分成?部分进行输入,每部分输入格式相同。 每部分第一行输入一个整数??,表示第?位同学连边的数目。 接下来??行,每行两个正整数?, ?,表示第?位同学将点?和点?之间进行连接。 可能会存在重边或者自环。 (1 ≤ ? ≤ 100000,1 ≤ ? ≤ 10,1 ≤ ?, ? ≤ ?, 0 ≤ ?? ≤ 200000)
题解:把点进行染色操作,每张图每个点对应一种颜色,那k张图就对应一个颜色序列,颜色序列完全一致的两个点,就能说明在k张图中都是联通的
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
vector<int> v[N];
int n,k,m;
vector<int> color[N];
map<vector<int>,int>mp;
int vis[N],cnt;
void dfs(int u)
{
int len=v[u].size();
int to;
vis[u]=1;
color[u].push_back(cnt);
for(int i=0;i<len;i++)
{
to=v[u][i];
if(vis[to]) continue;
dfs(to);
}
}
int main()
{
int x,y;
scanf("%d%d",&n,&k);
while(k--)
{
for(int i=1;i<=n;i++)
{
v[i].clear();
vis[i]=0;
}
scanf("%d",&m);
for(int i=1;i<=m;i++)
{
scanf("%d%d",&x,&y);
v[x].push_back(y);
v[y].push_back(x);
}
cnt=0;
for(int i=1;i<=n;i++)
{
if(!vis[i])
{
cnt++;
dfs(i);
}
}
}
for(int i=1;i<=n;i++)
{
mp[color[i]]++;
}
for(int i=1;i<=n;i++)
{
printf("%d\n",mp[color[i]]);
}
return 0;
}