您的位置:首页 > 其它

hdu1272小希的迷宫

2015-12-12 11:41 405 查看
题目描述:

输入任意组,两两连通的数据,最后以0,0结尾,判断所有的点是不是在一棵树上,并且不构成环。

这个题目应该注意的是:当输入0,0的时候应该是符合题意的,

   当输入1,2   2,1    0,0 的时候是不符合题意的  应为构成了环

  输入的不一定是从1开始  也不一定是连续的输入

                                            当在hdu oj上提交总是WA的时候  把c++改为g++可能就a了

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
#define MAXN 100005
int pre[MAXN], vis[MAXN];
int jishu = 0; //代表合并了几次
int find(int n)
{
return n == pre
? n : pre
= find(pre
); //递归式 查找当前节点的根节点 压缩路径
}

int unionFri(int x,int y) //合并两个节点 使之有共同根节点
{
int findX = find(x); //找到一个节点的根节点
int findY = find(y);
if(findX != findY) //如果两个节点不是同一个根节点 合并
{
pre[findX] = findY;
jishu++; //每合并一次计数器就+1 与主函数的i等待比较
}
return jishu;
}
int main()
{
int m,n;
int i=0;
int sum;
for(int i=1;i<MAXN;i++)
pre[i] = i; //初始化所有的根节点
memset(vis, 0 ,sizeof(vis));
while(scanf("%d%d",&m,&n)&&m!=-1&&n!=-1)
{
if (i == 0 && m == 0 && n == 0) //当输入0,0的时候就直接输出yes
{
puts("Yes");
continue;
}
if(m && n) //当不结束的时候
{
i++; //主函数的计数器++
vis[m] = vis
= 1; //因为题目要求不一定连续 而且不一定从1开始 所以要标记 每个进来的节点
sum = unionFri(m,n); //合并两个节点 返回函数内部计数器
}
else
{
if(i == sum) //如果函数内部的计数器和主函数的计数器相等 进行下面的判断
{
int k =0, tmp = -1; //tmp用在后面保存
for(int j=1;j<MAXN;j++) //因为是不连续的 所以遍历所有
if (vis[j]) //如果是输入过的 进入
{
if (tmp == -1) //当第一次进入的时候 找到第一个节点
tmp = find(j);//保存第一个节点的根节点
else if (tmp!=find(j)) //如果一个根节点和后面的根节点 又不是同一个的 计数器++ 并退出循环
{
k++;
break;
}
}
if(k == 0)
printf("Yes\n");
else
printf("No\n");
}
else
printf("No\n"); //如果函数内部计数器 和主函数计数器不相等直接输出no
i=0;//下面是对所有的东西进行初始化
jishu = 0;
for(int i=1;i<MAXN;i++)
pre[i] = i;
memset(vis, 0 ,sizeof(vis));
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: