poj-1611-The Suspects(水并查集)

来源:互联网 发布:java 创建文件夹失败 编辑:程序博客网 时间:2024/06/05 05:55

题目链接:http://poj.org/problem?id=1611

题意:输入n个人,m个组。初始化0为疑似病例。输入m个小组,每组中只要有一个疑似病例,整组人都是疑似病例。相同的成员可以在不同的组。找出一共有多少个疑似病例。

解题思路:同组的同parent,查找,合并集合。最后将出现的每个组员的parent和0的parent相比较,统计便可。

AC代码:

#include<iostream>#include<algorithm>using namespace std;#define ma 300010int fa[ma],m,n;int h[ma];int member[ma];int Count = 1;void init(int a){  for(int i = 0; i < a; i++)  {    fa[i] = i;    h[i] = 0;  }  return;}int Find(int x){  if(fa[x] == x)   return x;  else   return fa[x] = Find(fa[x]);}void unite(int x,int y){  x = Find(fa[x]);  y = Find(fa[y]);  if(x == y) return;  else  {    if(h[x] > h[y]) fa[y] = fa[x];    else    {      fa[x] = fa[y];      if(h[x] == h[y]) h[y]++;    }  }}bool same(int x, int y){ return Find(x) == Find(y);}inline void solve(int n,int m){    init(n);    while(m--)    {      int a;      cin>>a;      for(int i = 0; i < a; i++)        cin>>member[i];      //sort(member,member+a*sizeof(int));      for(int i = 1; i < a; i++)       unite(member[i-1],member[i]);    }    for(int i = 1; i < n; i++)      if(same(0,i)) Count++;    cout<<Count<<endl;}int main(){  while(cin>>n>>m)  {    if(!n) break;    solve(n,m);    Count = 1;  }  return 0;}


0 0