百练上全局题号是1611,POJ题号貌似是613.现在还搞不清楚全局题号是什么。
这是一道最近简单的并查集问题,注意的一点就是,合并的时候一定要把小序号作为父母节点,这样,所有跟0相关的节点,最后都会指向0节点。代码自带缩短路径。
#include <iostream>
#include <stdio.h>
using namespace std;
#define MAX_SIZE 30000+10
int p[MAX_SIZE];
int Init_Array(int n)
{
for (int i = 0; i < n; i++){
p[i] = i;
}
return 0;
}
int Find_parent(int i)
{
if (p[i] != i){
p[i] = Find_parent(p[i]);
}
return p[i];
}
bool Unit_ij(int i, int j)
{
int temp;
int Pi = Find_parent(i);
int Pj = Find_parent(j);
if (Pi != Pj){
if(Pj > Pi){
temp = Pi;
Pi = Pj;
Pj = temp;
}
p[Pi] = Pj;
}
return true;
}
int main()
{
int n,m; //m record the number of teams
int num; //num record the number of teammates
int first; //the first number of the teammates
int next; //the next number of the teammates
int count; //the suspects
while(cin>>n && n != 0){
cin>>m;
Init_Array(n);
count = 0;
for(int i = 0;i < m;i++)
{
cin>>num;
cin>>first;
for(int j = 1;j < num;j++)
{
cin>>next;
Unit_ij(first,next);
}
}
for(int i = 0;i < n;i++)
{
if(Find_parent(i) == 0)
count++;
}
cout<<count<<endl;
}
return 0;
}