题目:http://acm.hdu.edu.cn/showproblem.php?pid=1272
关键点:
1.特别小心输入的格式,这个比较纠结。
2.题目的最关键点:
(1).所有点的根节点都相同(即下面的count=1),
(2).输入路径不存在回来,这里用flag来标记回来(即构成回路,flag=1)
3.注意find3(int x)这里用路径压缩的话,速度会快很多(用空间来换时间)。
AC代码:
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <memory.h>
using namespace std;
int set[100001]={0},c[100001]={0};
//find x root
int find2(int x){
int r;
r = x;
while(r != set[r])
r = set[r];
return r;
}
//find x root and Path compression.
void find3(int x){
int r,i,j;
r = x;
//first,find root
while(r != set[r])
r = set[r];
i = x;
while(i != set[i]){
j = set[i];
set[i] = r;
i = j;
}
}
int main(){
int i,j,k,flag,x,y,count;
while(cin>>x>>y&&(x != -1 || y != -1)){
flag = 0;
k = 1;
count = 0;
if(x == 0 && y == 0){
cout<<"Yes"<<endl;
continue;
}
memset(c,0,sizeof(c));
for(i = 1; i <= 100001; i++)
set[i] = i;
while(x != 0 || y!= 0 ){
if(find2(x) != find2(y)){
set[find2(x)] = find2(y);
c[k++] = find2(y);
}
else
flag = 1;
cin>>x>>y;
}
if(flag == 1) {
cout<<"No"<<endl;
continue;
}
sort(c+1,c+k);
i = 1;
while(c[i] != 0)
{
find3(c[i]);
i++;
}
i = 1;
//count = 0;
while(c[i] != 0){
if(find2(c[i]) == i)
count ++;
i++;
}
if(count == 1&& flag != 1)
cout<<"Yes"<<endl;
else
cout<<"No"<<endl;
}
return 0;
}