原题链接:
The Suspects
题目大意:
严重急性呼吸系统综合症( SARS), 一种原因不明的非典型性肺炎,从2003年3月中旬开始被认为是全球威胁。为了减少传播给别人的机会, 最好的策略是隔离可能的患者。
在Not-Spreading-Your-Sickness大学( NSYSU), 有许多学生团体。同一组的学生经常彼此相通,一个学生可以同时加入几个小组。为了防止非典的传播,NSYSU收集了所有学生团体的成员名单。他们的标准操作程序(SOP)如下:
一旦一组中有一个可能的患者, 组内的所有成员就都是可能的患者。
然而,他们发现当一个学生被确认为可能的患者后不容易识别所有可能的患者。你的工作是编写一个程序, 发现所有可能的患者。
思路:
因为只要和编号为“0”的学生有关系,就肯定是嫌疑人,所以用并查集列出一颗树;
然后找到和编号“0”一个根节点的,就说明此人和编号为“0”的学生有关系。
试过好几遍,总是超时,但是答案是正确的。。
我也不知道为什么。。
不知道有没有大神帮忙看看为什么超时。
下面是超时代码:
#include<iostream>
using namespace std;
const int maxn = 30005;
int parent[maxn];
void chushuhua(int);
int find_root(int);
void union_root(int, int);
int main()
{
while (1)
{
int total_num, group;
scanf("%d%d", &total_num, &group) != EOF;
if (total_num == 0 && group == 0)
break;
chushuhua(total_num);
while (group--)
{
int text;
scanf("%d", &text);
if (text == 1) //如果text数据只有一个人,就不用管了;
continue;
int xxx, yyy;
for (int i = 0; i < text; i++)
{
if (i == 0)
{
scanf("%d", &xxx);
continue;
}
scanf("%d", &yyy);
union_root(xxx, yyy);
}
}
int sum = 0;
for (int i = 0; i < total_num; i++)
{
if (find_root(0) == find_root(i))
{
sum++;
}
}
printf("%d\n", sum);
}
return 0;
}
void chushuhua(int x)
{
for (int i = 0; i <= x; i++)
{
parent[i] = i; //根节点是自己;
}
}
int find_root(int x)
{
if (parent[x] == x) //如果是根节点就是自己;
return x;
else
return parent[x] = find_root(parent[x]); //递归找根节点;
}
void union_root(int x, int y)
{
int x_root = find_root(x);
int y_root = find_root(y);
if (x_root != y_root)
{
parent[y_root] = x_root;
}
}
这个是试过之后AC的代码:
#include<iostream>
using namespace std;
int parent[30005];
int temp[30005];
int find_root(int);
void union_root(int, int);
int main()
{
int mum, group;
while (cin>>mum>>group)
{
if (mum == 0 && group == 0)
break;
int sum=0;
for (int i = 0; i <= mum; i++)
{
parent[i] = i;
}
for (int i = 0; i < group; i++)
{
int k;
cin >> k;
if (k >= 1)
{
cin >> temp[0];
for (int j = 1; j < k; j++)
{
cin >> temp[j];
union_root(temp[0], temp[j]);
}
}
}
for (int i = 0; i <= mum; i++)
{
if (find_root(i) == parent[0])
{
sum++;
}
}
cout << sum << endl;
}
return 0;
}
int find_root(int x)
{
if (parent[x] == x)
return x;
else
return parent[x] = find_root(parent[x]);
}
void union_root(int x, int y)
{
int xx, yy;
xx = find_root(x);
yy = find_root(y);
if (xx != yy)
{
parent[yy] = xx;
}
}