标签:des style blog http color os io for ar
Description
Input
Output
Sample Input
6 8 5 3 5 2 6 4 5 6 0 0 8 1 7 3 6 2 8 9 7 5 7 4 7 8 7 6 0 0 3 8 6 8 6 4 5 3 5 6 5 2 0 0 -1 -1
Sample Output
Case 1 is a tree. Case 2 is a tree. Case 3 is not a tree.
Source
完全看不到并查集的影子了。。。此题就是拿并查集父子节点的关系来模拟一个图,在输入过程中,如果一个子节点被多个父节点连接,或一个节点的边自己指向自己,则可直接判定不是有根树,若输入过程中不能直接判定,整个图的父子关系建立完成后,也可通过并查集查找每个节点的根节点来判定是否为有根树,若每个节点的根节点有不同的,则表明此图有多个根节点,不是有根树,若并查集查找过程中递归次数超过一定大小(1000),则可视作为死循环,表明图中有环,也可判定不是有根树。此题的判定限制条件很多,千万不能有漏掉的。
#include <iostream> #define MAXN 1010 using namespace std; struct Node { int f,used; //f=父节点,used=1表示该点已经和其他点连接上了 }node[MAXN]; void MakeSet() { for(int i=0;i<MAXN;i++) { node[i].f=0; node[i].used=0; } } int findSet(int num,int step) { if(step>1000) return -5; //为环 if(node[num].f==0) return num; return findSet(node[num].f,step+1); } void AddEdge(int a,int b) //建立有向边a->b { node[a].used=1; node[b].used=1; node[b].f=a; } int main() { int s,t,CASE=0; while(1) { bool isTree=true; CASE++; MakeSet(); while(cin>>s>>t&&s>0) { if(s==t) isTree=false; else if(node[t].f==0) AddEdge(s,t); //子节点t没有和其他点连接,可以加新边 else isTree=false; //否则子节点t已经和其他点连接,不是树 } if(s==0) { if(!isTree) //已经确定不是一棵有根树 { cout<<"Case "<<CASE<<" is not a tree."<<endl; continue; } int root=0,times=0; for(int i=1;i<1000;i++) { if(node[i].used==1) //点i和其他边连接 { if(times==0) //第一次查找 root=findSet(i,1); //确定一个根节点root else if(root!=findSet(i,1)||findSet(i,1)<0||root<0) //如果点i的根节点不是之前确定的根节点(有多个根节点),或存在环,则不是树 { isTree=false; break; //不用再找了 } times++; } } if(isTree) cout<<"Case "<<CASE<<" is a tree."<<endl; else cout<<"Case "<<CASE<<" is not a tree."<<endl; } else break; } return 0; }
[POJ 1308]Is It A Tree?(并查集判断图是否为一棵有根树)
标签:des style blog http color os io for ar
原文地址:http://blog.csdn.net/qpswwww/article/details/38779693