通信系统
个人思路
本题就是一个并查集的基本操作。
- 并查集初始化
- 根据输入数据两两合并
- 查找根节点并计数,判断所有点均在一个集合内,输出yes,否则为no
有两个值得注意的地方
- 本题注明要每个节点均要收到消息,并且不能重复收到消息,也就是说N个结点都要在一个树型集合内(图则会出现环路),根据树的性质,N个结点连通必须有N-1条边,因此M = N - 1才符合条件(可以把这个判断条件放在最前面,省去多余计算提高运算效率)
- 由于Codeup是多点测试,要记得每次对全局变量初始化(写PAT没有养成初始化的习惯,找了半天的错误)
个人思路代码
#include <bits/stdc++.h>
using namespace std;
int N, M;
int father[1005];
bool vis[1005];
void init()//初始化
{
for(int i = 1; i <= N; ++i)
{
father[i] = i;
}
}
int findFather(int x)
{
if(x == father[x])
return x;
else
{
int F = findFather(father[x]);
father[x] = F;
return F;
}
}
void unionFather(int x, int y)
{
int fx = findFather(x);
int fy = findFather(y);
if(fx != fy)
father[fx] = fy;
}
int main(int argc, char *argv[]) {
while(1)
{
memset(father, 0, sizeof(father));
memset(vis, false, sizeof(vis));
scanf("%d%d", &N, &M);
if(!M && !N)
break;
init();
for(int i = 0; i < M; ++i)
{
int a, b;
scanf("%d%d", &a, &b);
unionFather(a, b);
}
int ans = 0;
for(int i = 1; i <= N; ++i)
{
int F = findFather(i);
if(!vis[F])
{
ans++;
vis[F] = true;
}
if(ans > 1)
{
break;
}
}
if(ans == 1 && M == N - 1)
printf("Yes\n");
else
printf("No\n");
}
return 0;
}