您的位置:首页 > 其它

HDU 1272 小希的迷宫 并查集

2013-06-17 21:54 435 查看
题目地址: http://acm.hdu.edu.cn/showproblem.php?pid=1272

1、判断是不是只有一个连通量。

2、判断有没有环

代码如下:

#include <iostream>
#include <vector>
#include <list>
#include <deque>
#include <queue>
#include <iterator>
#include <stack>
#include <map>
#include <set>
#include <algorithm>
#include <cctype>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <cmath>
using namespace std;

const int N=100011;
typedef long long LL;

int parent
,flag;
bool vis
;

void build()
{
for(int i=0;i<N;i++)
parent[i]=i;
}

int find(int x)
{
int r = x;
while (parent[r] != r)   //循环结束,则找到根节点
r = parent[r];
int i = x;
while (i != r) //本循环修改查找路径中所有节点
{
int j = parent[i];
parent[i] = r;
i = j;
}
return r;
}

void uniou(int x,int y)
{
x=find(x);
y=find(y);
if(x==y)
flag=1;
else
parent[x]=y;
}

void liantong()
{
int i,sum=0;
for(i=1;i<N;i++)
{
if(!vis[i]&&parent[i]==i)//i存在,且parent[i]==i,一个连通
sum++;
if(sum>1)
{
flag=1;break;
}
}
}

int main()
{
int i,j,a,b;
while(scanf("%d%d",&a,&b))
{
if(a==-1&&b==-1)    break;
if(a==0&&b==0)
{
printf("Yes\n");
continue;
}
memset(vis,true,sizeof(vis));
build();
flag=0;
uniou(a,b);
vis[a]=vis[b]=false;
while(scanf("%d%d",&a,&b))
{
if(a==0&&b==0)  break;
uniou(a,b);
vis[a]=vis[b]=false;
}
liantong();
if(flag==0)
printf("Yes\n");
else
printf("No\n");
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: