https://acm.ecnu.edu.cn/contest/173/problem/C/
题意:
给你k张图,每个图有点和边。输出每个点1 2...n的点在每张图里面都联通的点的个数。
思路:
染色也行,并查集也行。在k张图里面给每个点染色。
比如有3个点,4张图。染色情况如下
点1:1 1 1 1
点2:1 1 2 2
点3:1 1 2 2
将每个点的k个染色情况作为Map的key,点2(1 1 2 2)=点3(1 1 2 2)说明两个染色情况一样。就说明两个点在所有的图中都是来南通的。
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
const int maxn=100005;
int fa[11][maxn],a,b;
map<vector<int>,int> Map;
vector<int> v[maxn];
int find(int x,int k){
if(fa[k][x]==x) return x;
else return fa[k][x]=find(fa[k][x],k);
}
void unit(int x,int y,int k){
x=find(fa[k][x],k);
y=find(fa[k][y],k);
fa[k][x]=fa[k][y];
}
int main()
{
int n,k,m;
scanf("%d%d",&n,&k);
for(int i=1;i<=k;i++){
for(int j=1;j<=n;j++) fa[i][j]=j;
scanf("%d",&m);
for(int j=0;j<m;j++){
scanf("%d%d",&a,&b);
if(find(fa[i][a],i)!=find(fa[i][b],i)){
unit(fa[i][a],fa[i][b],i);
}
}
}
for(int i=1;i<=k;i++){
for(int j=1;j<=n;j++){
v[j].push_back(find(fa[i][j],i));
}
}
for(int i=1;i<=n;i++){
Map[v[i]]++;
}
for(int i=1;i<=n;i++) printf("%d\n",Map[v[i]]);
return 0;
}