一个简单的并查集的运用、、、找到与第一个有关系的人、、
#include <stdio.h>
#include <stdlib.h>
#define MAXN 30010
int p[MAXN];
int find_f(int x)
{
return p[x] == x ? x : (find_f(p[x]));
}
void rank(int a, int b)
{
int x = find_f(a), y = find_f(b);
if(x != y) p[x] = y;
}
int main()
{
int n, m, i, a, b, cnt, k;
while(scanf("%d %d", &n, &m) == 2 && (n != 0 || m != 0))
{
cnt = 0;
for(i=0; i<n; i++) p[i] = i;
for(i=0; i<m; i++)
{
scanf("%d", &k);
if((k--)>0) scanf("%d", &a);
while(k--)
{
scanf("%d", &b);
rank(a, b);
}
}
int t = find_f(0);
for(i=0; i<n; i++) if(find_f(i) == t) cnt++;
printf("%d\n", cnt);
}
return 0;
}
路径压缩写法:(时间快了50倍啊)
#include <algorithm>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <iomanip>
#include <stdio.h>
#include <string>
#include <queue>
#include <cmath>
#include <stack>
#include <map>
#include <set>
#define eps 1e-7
#define M 10001000
#define LL __int64
//#define LL long long
#define INF 0x3f3f3f3f
#define PI 3.1415926535898
const int maxn = 101000;
using namespace std;
int p[maxn];
int find_f(int x)
{
//return p[x] == x ? x : (find_f(p[x]));
int r = x;
while(p[r] != r)
r = p[r];
int i = x;
int j;
while(p[i] != r)
{
j = p[i];
p[i] = r;
i = j;
}
return r;
}
void rank(int a, int b)
{
int x = find_f(a), y = find_f(b);
if(x != y) p[x] = y;
}
int main()
{
int n, m, i, a, b, cnt, k;
while(scanf("%d %d", &n, &m) == 2 && (n != 0 || m != 0))
{
cnt = 0;
for(i=0; i<n; i++) p[i] = i;
for(i=0; i<m; i++)
{
scanf("%d", &k);
if((k--)>0) scanf("%d", &a);
while(k--)
{
scanf("%d", &b);
rank(a, b);
}
}
int t = find_f(0);
for(i=0; i<n; i++) if(find_f(i) == t) cnt++;
printf("%d\n", cnt);
}
return 0;
}