1 #include <iostream>
2 #include <cstdlib>
3 #include <cstdio>
4 #include <algorithm>
5 using namespace std;
6
7 const int M = 100005;
8 int a, b;
9 int father[M]; //记录父节点
10 bool circle; //判断是否存在环
11 bool visit[M]; //用来记录顶点数
12 int edgenum, vnum; //分别表示边数,顶点数
13
14 void initial()
15 {
16 for (int i = 0; i<M; i++)
17 father[i] = i, visit[i] = false;
18 circle = false;
19 edgenum = vnum = 0;
20 }
21
22 //(查)
23 int find(int x)
24 {
25 return x == father[x] ? x : father[x] = find(father[x]); //找祖先节点 + 路径压缩
26 }
27
28 //(并)
29 void merge(int a, int b)
30 {
31 if (a == b)
32 circle = true;
33 int x, y;
34 x = find(a);
35 y = find(b);
36 if (x != y)
37 {
38 father[x] = y;
39 edgenum++; //引出一条边
40 }
41 else
42 circle = true; //x==y,说明他们是同一个祖先,一旦连通便与祖先3者成环
43 }
44
45 int main()
46 {
47 while (true)
48 {
49 initial();
50 scanf("%d%d", &a, &b);
51 if (a == 0 && b == 0)
52 { //为空树
53 printf("Yes\n");
54 continue;
55 }
56 if (a == -1 && b == -1)
57 break;
58 visit[a] = true;
59 visit[b] = true;
60 merge(a, b);
61 while (true)
62 {
63 scanf("%d%d", &a, &b);
64 if (a == 0 && b == 0)
65 break;
66 visit[a] = true;
67 visit[b] = true;
68 merge(a, b);
69 }
70 for (int i = 0; i < M; i++)
71 {
72 if (visit[i])
73 vnum++;
74 }
75 if (!circle && edgenum + 1 == vnum)
76 printf("Yes\n");
77 else
78 printf("No\n");
79 }
80 return 0;
81 }