Sample Input
3 5
1 a
2 a
1 b
2 c
3 cSample Output
2 2 2
题解:维护一个并查集,每当检查到相邻两条消息相同且发送人不同时,将两个人加入同一集合,最后遍历统计所有集合每个包含的元素数量,就ok了。
我的代码:
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <set>
using namespace std;
#define LL long long
#define zero(a) memset(a,0,sizeof(a))
const LL INF = 0x3f3f3f3f;
const int mod = 1e9+7;
const int N = 1e5+5;
int father[N], nn, mm;
int dist[N], size[N];
int a[N];
void init(){
for(int i=1; i<=nn; ++i){
father[i] = i, dist[i] = 0, size[i] = 1;
}
zero(a);
}
int get(int x){
if(father[x] == x){
return x;
}
int y = father[x];
father[x] = get(y);
dist[x] += dist[y];
return father[x];
}
void merge(int a,int b){
a = get(a);
b = get(b);
if(a!=b){
father[a] = b;
dist[a] = size[b];
size[b] += size[a];
}
}
int main()
{
scanf("%d%d",&nn,&mm);
init();
char s[N], ss[N];
int t, tt;
mm--;
scanf("%d %s",&tt, ss);
while(mm--){
scanf("%d %s",&t, s);
if(t!=tt && strcmp(s, ss)==0)
merge(t, tt);
strcpy(ss, s);
tt = t;
}
for(int i=1; i<=nn; ++i){
++a[get(i)];
}
for(int i=1; i<=nn; ++i){
printf("%d ",a[get(i)] - 1);
//printf("#%d f=%d\n", a[i],father[i]);
}
return 0;
}