题目链接:
HDU 1272 小希的迷宫
题意:
给出若干匹配点,a,b,表示a,b之间有一条通路,问任意两点间是否有且只有一条通路?
分析:
每次读入判断a,b是否已经连通,如果已经连通了,那就是不符合的情况,否则就要将a,b两点合并。
还有一条就是要保证任意两点间都连通了,遍历每个点检查一遍即可。
注意:
如果一个测试样例只有0,0,那么输出Yes。//坑
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int maxn=100010;
int pre[maxn],a,b,vis[maxn],maxnum;
void init()
{
maxnum=-1;
memset(vis,0,sizeof(vis));
for(int i=0;i<maxn;i++)
pre[i]=i;
}
int find(int x)
{
int r=x;
while(pre[r]!=r)
r=pre[r];
int i=x,j;
while(pre[i]!=i)
{
j=pre[i];
pre[i]=r;
i=j;
}
return r;
}
void mix(int x,int y)
{
int fx=find(x);
int fy=find(y);
if(fx!=fy)
{
if(fx>fy) swap(fx,fy);
pre[fx]=fy;
}
}
int main()
{
//freopen("in.txt","r",stdin);
while(~scanf("%d%d",&a,&b))
{
if(a==-1&&b==-1) break;
if(a==0&&b==0)
{
printf("Yes\n");
continue;
}
init();
mix(a,b);
vis[a]=vis[b]=1;
maxnum=max(maxnum,a);
maxnum=max(maxnum,b);
int ok=0;
while(1)
{
scanf("%d%d",&a,&b);
if(a==0&&b==0) break;
vis[a]=vis[b]=1;
maxnum=max(maxnum,a);
maxnum=max(maxnum,b);
if(ok) continue;
if(find(a)==find(b)) ok=1;
mix(a,b);
}
if(ok) printf("No\n");//连通两点间不止一条路径
else //能连通的两点之间只有一条路径
{
ok=0;
int first=1;
int com=-1;
//cout<<maxnum<<endl;
for(int i=1;i<=maxnum;i++)
{
if(vis[i])
{
if(first==1)
{
com=find(i);
first=0;
}
else
{
if(find(i)!=com)
{
ok=1;
break;
}
}
}
if(ok) break;//有不连通的点
}
if(ok==0) printf("Yes\n");
else printf("No\n");
}
}
return 0;
}