这个题使用的算法是并查集。
这个题本身并不难,但我不会STL的map,所以数节点个数我就使用了二维数组,所以最好的题解还可以继续补充,这个题一个坑是它的输入结点不一定是从1开始的,也可能从其他数字开始,所以结点个数不是输入的最大数字,第二个坑是,根据图的定义,一个0结点0边的图形也是合法图,所以对于单独一个0 0输入我们也要输出Yes。
写题过程其实是构造数的过程,我们这里把根节点称为老大,如果输入的两个房间数我们发现它的老大是一样的,也就是它本身就是联通的,那么我们就知道如果将他们俩再直接连接就意味着会产生回路,就不符合题目要求了,这里我用flag标志,还有一个判定条件是结点个数=边个数+1,只有这样它才可能是符合小希要求的对于任意两个结点都只有唯一联通路径的简单图。
代码如下:
#include<bits/stdc++.h>
using namespace std;
int room[100005][2];
int ifind(int x)
{
while(room[x][0]!=x)
x=room[x][0];
return x;
}
void mercy(int a,int b)
{
int q=ifind(a);
int p=ifind(b);
if(q!=p)
room[q][0]=p;
}
int main()
{
int a,b,ans=0;;
int flag=1;
for(int i=1;i<=100005;i++)
{
room[i][0]=i;
room[i][1]=0;
}
int node_c=0;//一共有多少结点
while(cin>>a>>b)
{
if(a==0&&b==0)
{
//cout<<flag<<" "<<node_c<<" "<<ans<<endl;
if(node_c==0)//如果只输入0 0也要输出Yes
node_c=1;
if(flag&&ans==node_c-1)
cout<<"Yes"<<endl;
else
cout<<"No"<<endl;
getchar();
for(int i=1;i<=100005;i++)
{
room[i][0]=i;
room[i][1]=0;
}
flag=1;
ans=0;
node_c=0;
continue;
}
if(a==-1&&b==-1)
break;
if(a==b)
continue;
if(room[a][1]==0)
{
room[a][1]=1;
node_c++;
}
if(room[b][1]==0)
{
room[b][1]=1;
node_c++;
}
if(ifind(a)!=ifind(b))
{
mercy(a,b);
ans++;
}
else
{
flag=0;
//cout<<a<<" "<<b<<endl;
}
}
return 0;
}