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; }