并查集的应用。
遇到了两个问题。
开始时用简单的并查集,判断是否有重复的线,即有相同父节点的点不可以再次连接。
这种想法未考虑全连接的条件。即出现(1,2,3)(4,5)虽无圈但是未全连接。
加上全连接的条件,即在满足无循环的情况下,点的个数等于连接+1。
并且要加上没有输入点的情况也输出yes。
几经周折,AC的比较不容易。
#include <iostream>
using namespace std;
int city[100005] ;
int weight[100005] ;
int used[100005] ;
int findroot(int a) ;
void unionroot(int a, int b) ;
int main()
{
bool ans1 = true ;
bool ans2 = true ;
int a, b, roota, rootb, numcity, numlink ;
while(true)
{
ans1 = true ;
ans2 = true ;
numcity = 0 ;
numlink = 0 ;
for(int i = 1 ; i<100005 ; i++)
{
city[i] = i ;
weight[i] = 1 ;
used[i] = 0 ;
}
while(cin >> a >> b)
{
if(a==0&&b==0)
break ;
if(a==-1&&b==-1)
return 0 ;
numlink++;
used[a] = 1 ;
used[b] = 1 ;
roota = findroot(a) ;
rootb = findroot(b) ;
if(roota==rootb)
ans1 = false ;
else
unionroot(roota, rootb) ;
}
for(int i = 1 ; i < 100005 ; i++)
numcity+=used[i] ;
if(numcity!=numlink+1)
ans2 = false ;
if((ans1==true&&ans2==true)||numcity==0)
cout << "Yes" << endl ;
else
cout << "No" << endl ;
}
return 0;
}
int findroot(int a)
{
while(a!=city[a])
a = city[a] ;
return a ;
}
void unionroot(int a, int b)
{
if(weight[a]>weight[b])
{
city[b] = a ;
weight[a] += weight[b] ;
}
else
{
city[a] = b ;
weight[b] += weight[a] ;
}
}