题目描述
在某城市里住着n个人,任何两个认识的人不是朋友就是敌人,而且满足:
1、我朋友的朋友是我的朋友;
2、我敌人的敌人是我的朋友;
所有是朋友的人组成一个团伙。告诉你关于这n个人的m条信息,即某两个人是朋友,或者某两个人是敌人,请你编写一个程序,计算出这个城市最多可能有多少个团伙?
输入格式
第一行为n和m,1<n<1000,1≤m≤100000;
以下m行,每行为p、x、y,p的值为0或1,p为0时,表示x和y是朋友,p为1时,表示x和y是敌人。
输出格式
一个整数,表示这n个人最多可能有几个团伙。
输入样例
6 4
1 1 4
0 3 5
0 4 6
1 1 2
输出样例
3
题解
如果输入两个人之间为朋友,那就直接合并;否则我们就先存下了唉,输入完之后,再合并每个人所有的敌人即可。
#include <iostream> #include <cstdio> #define MAX_N 1000 #define MAX_M 100000 using namespace std; int n; int m; int h[MAX_N + 5], p[MAX_M + MAX_M + 5], t[MAX_M + MAX_M + 5]; int r[MAX_N + 5]; int c[MAX_N + 5]; int ans; int Root(int x) { int R = x, tmp; while(R != r[R]) R = r[R]; while(x != r[x]) tmp = r[x], r[x] = R, x = tmp; return R; } int main() { scanf("%d%d", &n, &m); for(register int i = 1; i <= n; ++i) { r[i] = i; } int f, x, y; for(register int i = 1; i <= m; ++i) { scanf("%d%d%d", &f, &x, &y); if(f) { t[i] = y; p[i] = h[x]; h[x] = i; t[i + m] = x; p[i + m] = h[y]; h[y] = i + m; } else { if(Root(x) != Root(y)) { r[Root(y)] = Root(x); } } } for(register int i = 1; i <= n; ++i) { x = t[h[i]]; for(register int j = h[i]; j; j = p[j]) { if(Root(x) != Root(t[j])) { r[Root(t[j])] = Root(x); } } } for(register int i = 1; i <= n; ++i) { c[Root(i)] = 1; } for(register int i = 1; i <= n; ++i) { ans += c[i]; } printf("%d", ans); return 0; }