hdu 1272 并查集
来源:互联网 发布:淘宝联盟佣金是全店吗 编辑:程序博客网 时间:2024/05/19 02:39
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1272
题目要求:
就是判断一个无向图是否是连通图,并且这个图不能有环。。
这数据有点坑爹,当一组数据直接只有0 0 的时候要输出Yes,个人感觉0 0 表示的是没有这个图,为什么要输出Yes。这我也是看了别人说的才A的。
做这题的时候,一开始自己有点想当然了,;以为应该就只是连通图的判环问题而已,,结果还可以有连 连通图都不是的情况。。。
不过题目中确实明确说了希望 任意两个房间有且仅有一条路径可以相通 这确实指的就是需要是连通图。。
判断连通图的话就是用并查集判断所有数据输入合并之后判断一下是不是只有一个集合。。。
判断是否有环的话就是利用kruskal里面的方法,对于每一次输入检查一下一条边的两个点是不是在同一个集合之中,如果是在同一个集合之中的话,那么就说明这个图是存在环的。
还有要注意的一点就是,要掌握并查集里面非递归写法的find函数,这次用了递归写法的被告知爆栈orzzzzz
代码:
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;#define INF 0x3f3f3f3f#define M 100009int p[100009];int mark[100009];int find(int a){ //return a==p[a]?a:p[a]=find(p[a]); int r = a; while(r!=p[r]) { r = p[r]; } int i = a,j; while(i!=r) //如果i不是根节点 { j = p[i]; //保存当前的父节点 p[i] = r; //将每一个节点的父节点都变成根节点 i = j; //用之前的父节点更新i } return r;}bool uni(int a,int b){ int x = find(a); int y = find(b); if(x==y) return true; if(x!=y) p[x] = y; return false;}int main(){ while(1) { memset(p,0,sizeof(p)); memset(mark,0,sizeof(mark)); int num = 0; bool ok = false; for(int i = 0;;i++) { int a,b; scanf("%d %d",&a,&b); if(a==0 && b==0) break; if(a==-1 && b==-1) goto out; if(p[a]==0) p[a] = a; if(p[b]==0) p[b] = b; mark[a] = 1; mark[b] = 1; if(ok) continue; ok = uni(a,b); } if(ok) printf("No\n"); else { for(int i = 1;i <= M;i++) { if(i==p[i] && mark[i]) //如果是根节点并且有出现在输入之中。 { mark[i] = 1; num++; } if(num > 1) break; } if(num!=1&&num!=0) //num=0的时候就是0 0 输入的时候 printf("No\n"); else printf("Yes\n"); } } out: return 0;}
还有一份之前写挫的代码,虽然可以AC:
并不需要开show数组,而且判断的地方也很挫orzzz
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;#define INF 0x3f3f3f3fint p[100009];int mark[100009];int show[100009];int find(int a){ //return a==p[a]?a:p[a]=find(p[a]); int r = a; while(r!=p[r]) { r = p[r]; } int i = a,j; while(i!=r) { j = p[i]; p[i] = r; i = j; } return r;}bool uni(int a,int b){ int x = find(a); int y = find(b); if(x==y) return true; if(x!=y) p[x] = y; return false;}int main(){ while(1) { memset(p,0,sizeof(p)); memset(mark,0,sizeof(mark)); memset(show,0,sizeof(show)); int num = 0; bool ok = false; int max = -INF; for(int i = 0;;i++) { int a,b; scanf("%d %d",&a,&b); if(a==0 && b==0) break; if(a==-1 && b==-1) goto out; if(p[a]==0) p[a] = a; if(p[b]==0) p[b] = b; if(a>max) max = a; if(b>max) max = b; show[a] = 1;show[b] = 1; if(ok) continue; ok = uni(a,b); } if(ok) printf("No\n"); else { for(int i = 1;i <= max;i++) { if(!show[i]) continue; int temp = find(i); //找出根节点,其实可以直接写成if(p[i]==i) if(mark[temp]==0) { mark[temp] = 1; num++; } } if(num!=1&&num!=0) printf("No\n"); else printf("Yes\n"); } } out: return 0;}
0 0
- HDU-1272(并查集)
- HDU 1272 并查集
- HDU 1272 并查集
- hdu 1272 并查集
- HDU 1272 并查集
- hdu 1272 并查集
- hdu 1272并查集
- HDU 1272 并查集
- hdu 1272 并查集
- HDU 1272 并查集
- HDU 1272 并查集
- HDU 并查集 1272
- hdu 1272 并查集
- HDU 1272(并查集)
- HDU 1272 (并查集)
- hdu 1272 并查集简单题目
- hdu 1272 并查集模版
- hdu--1272--并查集(捏个捏个)
- 使EditText有四边框的最快方法
- ios tableView那些事 (十六) UITableView中Cell重用机制导致内容重复解决方法
- 关于 RtlCaptureContext
- android更换头像问题
- ios tableView那些事 (十四) 获取 tableview 每个cell 的坐标点
- hdu 1272 并查集
- 安卓和ios App 标示机器的方式(mac地址 ,idfa)
- 添加巡检报告注意事项
- 第五周 项目4-静态成员应用
- 第五周项目三 用多文件组织多个类的程序(项目二)
- 【BZOJ3907】网格 组合数,补集转换
- JAVA中接口和抽象类的区别?
- Hadoop Hive sql语法详解
- SpringMVC重定向视图RedirectView小分析