开始第一反应是科鲁斯卡最小生成树,以为只要判断两点是否在同一个集合就行了,没注意到条件说要构成连通图(最小生成树)而且还有坑爹的0 0这种空测试数据,下次注意
主要思路很简单:1,判断两点是否同一集合。2,统计边和点的数量,要满足v-1 = e;
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <string>
#include <map>
#include <queue>
#include <numeric>
#include <stack>
using namespace std;
#define el else
const int MAX_N = 1e5 + 10;
int fa[MAX_N];
bool vis[MAX_N]; //点是否出现过
int get(int x) {
if (fa[x] == x) {
return x;
}
return fa[x] = get(fa[x]);
}
void joint(int x, int y) {
int xx = get(x);
int yy = get(y);
if (xx != yy) {
fa[xx] = yy;
}
}
int main()
{
int n, m;
int f;
int e = 0;
int v = 0; //边和点
while (scanf("%d%d", &n, &m), n != -1 && m != -1) {
if (n == 0 && m == 0) {
puts("Yes");
continue;
} //0 0直接yes
f = 1, memset(vis, 0, sizeof(vis));
vis[n] = 1, vis[m] = 1;
iota(fa, fa + MAX_N, 0); //G++标准函数,递增填充数组或容器
joint(n, m);
e = 1; //初始化一切
while (scanf("%d%d", &n, &m), n != 0 && m != 0) {
if (get(n) == get(m)) {
f = 0;
continue;
}
else {
joint(n, m);
vis[n] = 1;
vis[m] = 1;
++e;
//cout << e << " ";//
}
}
//cout << endl;
v = 0;
for (int i = 0; i < MAX_N; ++i) {
if (vis[i]) ++v;
} //统计点的个数
if (f == 1 && e == v - 1)puts("Yes");
else puts("No");
}
return 0;
}