HDU-1325-Is It A Tree?
2012-08-26 12:01
274 查看
题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=1325
程序分析:
这道题跟小希的迷宫有很大的相似吧,只是一个是无向图一个是有向图。也是给你那些结点之间的信息,然后让你判断是不是一颗树罢了,用树的定义来判断吧,无环,n个结点最多有n-1条边,不然就会有环。只有一个入度为0的结点,不存在入度大于1的结点。这些也足以判断是否为一棵树了吧。不过要注意一些特殊数据的情况,空树也是树。比如输入0 0。
解决方法:
其实也可以不用并查集,这样就可以直接按照上面的条件来统计,就可以判断是不是一颗树了。方法有多种,都知道最好,但是得精通,这些天都是在练并查集,所以我就用了并查集的思想来做吧,我加了个条件判断就是判断他村不存在环,这个是用到:如果两个不同的结点的根结点都相同,这样就会存在一个环或者有一个结点的入度会变为2了。只好也就不符合树的定义了。
控制输入数据时有点坑爹,输入停止条件应该是 a < 0 || b < 0,因为这个WA了很多次,最后是老大帮我改了之后就A了,一直还以为是数组不够大或者输入函数那些没写好,原来就是这么一个小BUG。学东西吧,错的多,改对了就能学会多一点。
View Code
程序分析:
这道题跟小希的迷宫有很大的相似吧,只是一个是无向图一个是有向图。也是给你那些结点之间的信息,然后让你判断是不是一颗树罢了,用树的定义来判断吧,无环,n个结点最多有n-1条边,不然就会有环。只有一个入度为0的结点,不存在入度大于1的结点。这些也足以判断是否为一棵树了吧。不过要注意一些特殊数据的情况,空树也是树。比如输入0 0。
解决方法:
其实也可以不用并查集,这样就可以直接按照上面的条件来统计,就可以判断是不是一颗树了。方法有多种,都知道最好,但是得精通,这些天都是在练并查集,所以我就用了并查集的思想来做吧,我加了个条件判断就是判断他村不存在环,这个是用到:如果两个不同的结点的根结点都相同,这样就会存在一个环或者有一个结点的入度会变为2了。只好也就不符合树的定义了。
控制输入数据时有点坑爹,输入停止条件应该是 a < 0 || b < 0,因为这个WA了很多次,最后是老大帮我改了之后就A了,一直还以为是数组不够大或者输入函数那些没写好,原来就是这么一个小BUG。学东西吧,错的多,改对了就能学会多一点。
View Code
#include<iostream> using namespace std; const int Max = 100000+10; int Far[Max]; int Rank[Max]; //改为标记结点的入度 int Sign[Max]; void Make_set(int n) { int i; for(i=0; i<n; i++) { Far[i] = i; } memset(Rank, 0, sizeof(Rank)); memset(Sign, 0, sizeof(Sign)); } int Find_set(int x) { if(Far[x] != x) return Far[x] = Find_set(Far[x]); return Far[x]; } void Unio(int a, int b) { a = Find_set(a); b = Find_set(b); if(a == b) return; //因为是有向图,合并方向必须只有一个 Far[b] = a; /* if(Rank[a] < Rank[b]) Far[a] = b; else if(Rank[a] > Rank[b]) Far[b] = a; else { Far[a] = b; Rank[b]++; }*/ } int main() { int a, b; //初始化 int flag = 1; int k = 1; Make_set(Max); while(cin>>a>>b ) { if(a < 0 || b < 0) return 0; if(a == 0 && b == 0) //待一组数据输入完毕后才输出结果 { int ans = 0; for(int i=1; i<Max; i++) { if(Sign[i] && Find_set(i) == i) //统计有几个连通分支 ans++; if(Rank[i] > 1) //存在有入度大于一的结点就不是树了,是图 { flag = 0; break; } } if(ans > 1) //连通分支大于1,表示是否为森林 flag = 0; if(flag) cout<<"Case "<<k++<<" is a tree."<<endl; else cout<<"Case "<<k++<<" is not a tree."<<endl; //从新初始化 flag = 1; //表示为Yes Make_set(Max); continue; } if(a != b && Find_set(a) == Find_set(b)) //根节点相同,但叶子不同,表示a,b已存在路径,如果 { //仍增加一条路径则会存在环,则有第二天路径 //cout<<"No"<<endl; flag = 0; } else { Sign[a] = 1; Sign[b] = 1; Rank[b] ++; //入度加一 Unio(a, b); //b的老大是a,只能是一个方向,因为是有向图 } } return 0; }
相关文章推荐
- hdu1325 Is It A Tree?(有向图并查集)
- HDU 1325 Is It A Tree?
- hdu 1325 Is It A Tree?(并查集)
- HDU 1325 Is It a Tree?
- hdu 1325 Is It A Tree?
- hdu 1325 Is It A Tree?
- hdu 1325 Is It A Tree?
- hdu 1325 Is It A Tree?(并查集)
- hdu 1325 Is It A Tree?
- 【并查集】HDU 1325 Is It A Tree?
- HDU 1325 Is It A Tree?(判断是否为树)
- hdu1325 Is It A Tree?并查集
- hdu1325 Is It A Tree? (并查集+森林)
- hdu-1325 & poj-1308 Is It A Tree?
- hdu 1325 Is It A Tree?
- HDU 1325 Is It A Tree?
- 【HDU - 1325】Is It A Tree?
- 【并查集】HDU 1325 Is It A Tree?
- TOJ 1856 POJ 1308 HDU 1325 Is It A Tree? / 并查集
- POJ 1308 && HDU 1325 Is It A Tree?(并查集)