题意
这道题是给出条路,然后问是否从中任选一个起点到任意一个终点的路径有且仅有一条。
思路
这很明显是一棵树状图,可以得到树状图有两个明显的特征:1.无环,这很容易用并查集来判断2.一棵树状图,顶点数永远比路径多1,这样要计算顶点数和路径数就可以喽~
代码
#include <cstdio>
#include <cstring>
const int maxn = 100000 + 20;
int pre[maxn];
int flag;
int cnt[maxn];
int cnt_l;
void init() {
for(int i = 1; i <= maxn; i++) {
pre[i] = i;
}
}
int find(int x) { // 查找根节点+路径压缩
int root = x;
int temp;
while(root != pre[root]) {
root = pre[root];
}
while(x != root) {
temp = pre[x];
pre[temp] = root;
x = temp;
}
return root;
}
int main()
{
// freopen("input.txt", "r", stdin);
int x, y;
while(true) {
flag = 1;
cnt_l = 0; // 边的个数
int T = 0;
int cntv = 0; // 顶点的个数
memset(cnt, 0, sizeof(cnt));
init();
while(~scanf("%d%d", &x, &y) && x && y) {
T+=2;
if (!flag) continue;
if (x == -1 && y == -1) goto END;
if (x == y) continue;
int fx = find(x);
int fy = find(y);
if (fx == fy) {
flag = 0;
}
else {
pre[fy] = fx;
cnt_l++;
cnt[x] = 1; // 标记顶点,最后统计顶点个数
cnt[y] = 1;
}
}
for(int i = 1; i < maxn; i++) { // 计算顶点的个数
if (cnt[i]) cntv++;
}
if (cntv != cnt_l + 1) flag = 0;
if (flag || !T) printf("Yes\n"); // 直接是0 0 也是合题的
else printf("No\n");
}
END:
return 0;
}