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;
}
输入任意组,两两连通的数据,最后以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;
}
相关文章推荐
- hdu 1754 I Hate It(线段树)
- BHO开发浏览器插件-Adding Toolbar Buttons
- 彻底理解android中的内部存储与外部存储
- 9_排序二叉树删除-1
- Associative机制使用场景
- poj3279 (搜索,好题**)
- 杭电1861 游船出租
- Hyper-v Server动态内存
- LeetCode Insert Interval
- 基于ZooKeeper的分布式Session实现
- Error when loading the SDK:解决方案
- android中sharedPreferences的用法与json和数组的互转
- 在Linux系统中使用Fish Shell的入门指引
- 基于rails的schedule网站开发(7):部署到heroku
- Gradle目录解析
- Android实现换肤的两种思路分析
- 压缩跟踪Compressive Tracking源码理解
- 简单易用的高速加密工具 BCArchive
- 抽象工厂(Abstact factory)模式
- hdoj--1342--Lotto(dfs)