您的位置:首页 > 其它

POJ1611 The Suspects (并查集)

2014-10-17 00:00 387 查看
本文出自:http://blog.csdn.net/svitter

题意:0号学生染病,有n个学生,m个小组。和0号学生同组的学生染病,病可以传染。

输入格式:n,m

数量 学生编号1,2,3,4

//m个分组

题解:最为典型的并查集。

解法一:求出所有的集合,然后求出0的parent,把parent为0的parent所有学生求出。

解法二:在计算的过程中统计total;

解法一:(一开始用的Vim写的在POJ上交出现 访问禁止错误- - 不知道又神奇的碰上了什么BUG,删了main函数中几个换行符就好了)

#include <iostream>
#include <stdio.h>
using namespace std;

int stu[30001];
//the num of stu, group
int n, m;

void init()
{
for(int i = 0; i < n; i++)
stu[i] = i;
}

int getParent(int a)
{
if(a == stu[a])
return a;
else
return stu[a] = getParent(stu[a]);
}

void Merge(int a, int b)
{
if(getParent(a) == getParent(b))
return;

else
stu[getParent(a)] = b;
}

int main()
{
int i, j;
int deter, sum;
int num;
int temp1, temp2;

while(scanf("%d%d", &n, &m))
{
if(n == 0 && m == 0)
break;
init();
for(i = 0; i < m; i++)
{
scanf("%d", &num);
scanf("%d", &temp1);
for(j = 1; j < num; j++)
{
scanf("%d", &temp2);
Merge(temp1, temp2);
}
}
deter = stu[getParent(0)];
sum = 1;
for(i = 1; i < n; i++)
{
if(getParent(i) == deter)
sum++;
}

printf("%d\n", sum);
}
return 0;
}


解法二:

#include <iostream>
#include <stdio.h>
using namespace std;

int stu[30001];
int total[30001];
//the num of stu, group
int n, m;

void init()
{
for(int i = 0; i < n; i++)
{
stu[i] = i;
total[i] = 1;
}
}

int getParent(int a)
{
if(a == stu[a])
return a;
else
return stu[a] = getParent(stu[a]);
}

void merge(int a, int b)
{
if(getParent(a) == getParent(b))
return;

else
{
total[getParent(a)] += total[getParent(b)];
stu[getParent(b)] = a;
}
}

int main()
{
int i, j;
int num;//record the group's num
int temp1, temp2;

while(scanf("%d%d", &n, &m))
{
if(n == 0 && m == 0)
break;
init();
for(i = 0; i < m; i++)
{
scanf("%d", &num);
scanf("%d", &temp1);
for(j = 1; j < num; j++)
{
scanf("%d", &temp2);
merge(temp1, temp2);
}
}

printf("%d\n", total[getParent(0)]);    //不能直接stu[0],因为stu[0]不一定是根节点。
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  算法 并查集