1.迄今为止做过的最费劲的一道题,到现在思路还不是很清楚;
2.主要考察并查集,并查集的概念(http://www.nocow.cn/index.php/%E5%B9%B6%E6%9F%A5%E9%9B%86)。到目前为止这种思想还没有。
3.并查集的主要操作,找父节点,合并,路径压缩;
4.刚开始WA,把100000改成100010后AC了就
以下是代码:
#include <stdio.h>
#include <iostream>
using namespace std;
int fath[100010], rank[100010], visit[100010];
void initial()
{
for(int i = 0; i < 100010; i++)
{
fath[i] = i;
rank[i] = 0;
visit[i] = 0;
}
}
int find(int x)
{
return fath[x] == x ? fath[x] : find(fath[x]);
}
bool unionSet(int x, int y)
{
int aa = find(x);
int bb = find(y);
if (aa == bb)
return false;
if (rank[aa] > rank[bb])
fath[bb] = aa;
else
{
fath[aa] = bb;
rank[bb] ++;
}
return true;
}
int main()
{
int a, b,i;
while (scanf("%d%d", &a, &b) != EOF && a + b != -2)
{
if( a + b == 0 )
{
cout << "Yes" <<endl;
continue;
}
initial();
unionSet(a, b);
visit[a] = visit[b] = 1;
int flag = 0;
while (scanf("%d%d", &a, &b) && a != 0 && b != 0)
{
if( !unionSet(a, b) )
flag = 1;
visit[a] = visit[b] = 1;
}
int cnt = 0;
for(i = 0; i < 100010; i++)
if(visit[i] == 1 && fath[i] == i)
cnt ++;
if (cnt > 1) flag = 1;
if(flag) cout << "No" << endl;
else cout << "Yes" << endl;
}
return 0;
}