poj1308 并查集
2015-09-08 21:27
267 查看
题意:和hdu1272差不多,只不过给出的是有向图,问图中的点是否是一颗树。
还是用并查集合并点,对于一条边,如果连接的两点已经在同一并查集内,则可以直接判否。合并时按边的方向记录点的入度,如果某个点入度大于1也就是某个点有多个父亲节点,则说明不是树。合并时顺便记录合并总次数,最后合并 点数-1 次则是树。
View Code
还是用并查集合并点,对于一条边,如果连接的两点已经在同一并查集内,则可以直接判否。合并时按边的方向记录点的入度,如果某个点入度大于1也就是某个点有多个父亲节点,则说明不是树。合并时顺便记录合并总次数,最后合并 点数-1 次则是树。
#include<stdio.h> #include<string.h> int fa[100005],num[100005]; bool vi[100005]; void init(){ for(int i=1;i<=100004;i++)fa[i]=i; } int find(int x){ int r=x,t; while(r!=fa[r])r=fa[r]; while(x!=r){ t=fa[x]; fa[x]=r; x=t; } return r; } int main(){ int a,b,c=0; while(scanf("%d%d",&a,&b)!=EOF&&a!=-1||b!=-1){ printf("Case %d is ",++c); if(a==0&&b==0){printf("a tree.\n");continue;} init(); memset(num,0,sizeof(num)); memset(vi,0,sizeof(vi)); bool f=1; int x=find(a),y=find(b),cnt=0,ans=0; if(!vi[a]){ cnt++; vi[a]=1; } if(!vi[b]){ cnt++; vi[b]=1; } num[b]++; if(num[b]>1)f=0; if(x!=y){ fa[x]=y; ans++; } else f=0; while(scanf("%d%d",&a,&b)&&a!=0||b!=0){ x=find(a),y=find(b); if(!vi[a]){ cnt++; vi[a]=1; } if(!vi[b]){ cnt++; vi[b]=1; } num[b]++; if(num[b]>1)f=0; if(x!=y){ fa[x]=y; ans++; } else f=0; } if(ans==cnt-1&&f)printf("a tree.\n"); else printf("not a tree.\n"); } return 0; }
View Code
相关文章推荐
- Linux网络属性配置管理及其相关命令
- Objective-C之深拷贝与浅拷贝
- 不看别人
- 代理模式
- lintcode-带重复元素的排列 -16
- hdu 4405 Aeroplane chess(概率dp)
- mysql group by 用法解析(详细)
- 完整版单例代码
- poj 3390 Print Words in Lines 动态规划
- Linux精品之NFS介绍与应用(双httpd + php-fpm + nfs + mysql 搭建discuz论坛)
- unity3D-----------socket客户端、服务器(简单)
- Spring定时任务的几种实现
- 第51讲:Scala中链式调用风格的实现代码实战及其在Spark编程中的广泛运用
- django 1.8 官方文档翻译: 2-5-7 自定义查找
- 简单Latex
- UI中的隐藏键盘的三个小方法
- [转] MemCached 的 stats 命令
- PIC16F887 SPI CAN 传输,操作MCP2515
- 第18章(二)TCP状态变迁图与2MSL等待状态
- hdu 4593 Robot