#Description
给你若干个连通关系
如果最后全部连通,并且形成树,就输出Yes,否则输出No
#Algorithm
并查集
每次来两个点,先判断是否在同一个集合,如果在一个,那就已经连通了,直接NO
然后就并起来
接下来考虑虽然不成环,不过可能不是连通的
所有
par[i] = i 的点数就是连通块的数量,如果这个数比1大,那也输出NO
#Code
#include <iostream>
#include <vector>
#include <cstring>
#include <cstdio>
using namespace std;
const int MAXL = 100000 + 9;
struct V
{
V(){}
V(int a, int b) : a(a), b(b) {};
int a, b;
};
vector<V> v;
bool b[MAXL];
int l;
int par[MAXL];
int urank[MAXL];
void init()
{
for (int i = 0; i < l; i++) {
par[i] = i;
urank[i] = i;
}
}
int find(int x)
{
if (par[x] == x) return x;
else return par[x] = find(par[x]);
}
void unite(int x, int y)
{
x = find(x);
y = find(y);
if (x == y) return;
if (urank[x] < urank[y]) {
par[x] = y;
} else {
par[y] = x;
if (urank[x] == urank[y]) urank[x]++;
}
}
bool same(int x, int y) {
return find(x) == find(y);
}
void solve()
{
memset(b, 0, sizeof(b));
init();
for (int i = 0; i < v.size(); i++) {
if (!b[v[i].a]) {
b[v[i].a] = true;
}
if (!b[v[i].b]) {
b[v[i].b] = true;
}
if (same(v[i].a, v[i].b)) {
puts("No");
return;
}
unite(v[i].a, v[i].b);
}
int t = 0;
for (int i = 0; i < l; i++) {
if (b[i] && par[i] == i) t++;
if (t == 2) {
puts("No");
return;
}
}
puts("Yes");
}
int main()
{
// freopen("in.txt", "r", stdin);
l = 0;
int a, b;
for (;;) {
scanf("%d%d", &a, &b);
if (a == -1 && b == -1) break;
if (a == 0 && b == 0) {
solve();
l = 0;
v.clear();
continue;
}
v.push_back(V(a - 1, b - 1));
l = max(l, max(a, b));
}
}