Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 18778 | Accepted: 6395 |
Descriptionnode
Inputios
Outputide
Sample Inputthis
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 Outputspa
Case 1 is a tree. Case 2 is a tree. Case 3 is not a tree.
题目大意:给出一些数字对,表明父节点和子节点,输入以0 0结束,问这些节点可否构成一棵树。
解题方法:判断可否构成一棵树的条件:1.空树是一棵树。2.树中不存在回路。3.森林不是树。能够用并查集判断是否存在回路,而后用并查集扫描一遍,看是否全部节点的最顶端父节点相同,不一样则为森林。
#include <stdio.h> #include <iostream> #include <string.h> using namespace std; typedef struct { int rank; int parent; }UFSTree; UFSTree Set[10000]; int Stack[10000];//用于保存每一个节点对中的父节点,以检测是否为森林 void MakeSet() { for (int i = 0; i < 10000; i++) { Set[i].rank = 0; Set[i].parent = i; } } int FindSet(int x) { if (x == Set[x].parent) { return x; } else { return FindSet(Set[x].parent); } } void UnionSet(int x, int y) { x = FindSet(x); y = FindSet(y); if (Set[x].rank > Set[y].rank) { Set[y].parent = x; } else { Set[x].parent = y; if (Set[x].rank == Set[y].rank) { Set[y].rank++; } } } int main() { int x, y, nCase = 1, top = 0; bool flag = true; MakeSet(); while(scanf("%d%d", &x, &y) != NULL && x != -1 && y != -1) { while(1) { if (x == 0 && y == 0) { break; } Stack[top] = x; top++; //若是两个节点处于同一集合,则不能造成一棵树 if (FindSet(x) == FindSet(y)) { flag = false; } else { UnionSet(x, y); } scanf("%d%d", &x, &y); } if (flag) { //查询每一个节点对中的父节点,看全部节点的最顶端父节点是否相同,不相同则为森林 for (int i = 0; i < top - 1; i++) { int n1 = FindSet(Stack[i]); int n2 = FindSet(Stack[i + 1]); if (n1 != n2) { flag = false; break; } } } if (flag) { flag = true; printf("Case %d is a tree.\n", nCase++); } else { flag = true; printf("Case %d is not a tree.\n", nCase++); } MakeSet(); top = 0; } return 0; }