程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> hdoj1325 Is It A Tree?,hdoj1325tree

hdoj1325 Is It A Tree?,hdoj1325tree

編輯:C++入門知識

hdoj1325 Is It A Tree?,hdoj1325tree


Is It A Tree?題目鏈接

題意: 
多組測試數據, 每組數據有多個數對, 表示一條有向邊(即第一個數是第二個數的父節點), 以 0,0 為一組測試數據結束標志。當輸入-1,-1時測試結束。 從那些給出的信息中判斷是否是一棵樹。 
分析: 
1、只可以有一個根節點, 也可以是一個點都沒有的空樹; 
2、除了根節點, 每個點只有一個父節點。 
3、因為只可以有一個父節點, 所以我們可以把一個合法的關系對(一個父親節點與孩子節點對)合並到一個集合裡, 他們的父節點都標記為所屬樹的根節點, 那樣我們方便判斷是否成環。 
4、判斷是否成環, 成環不可以。 
5、 還有一個很衰的地方, 注意不光輸入-1,-1 測試結束, 只要輸入兩個數都小於0就結束。

#include<iostream> #include<cstdio> #include<string.h> #include<math.h> #include<algorithm> using namespace std; const int N = 10005; int a, b, n, mi, mx, sum, flag, v[N], pre[N]; int find(int x)//尋找x所屬的樹的根節點 { int r, i, j; r = x; i = x; while(r != pre[r]) r = pre[r]; while(pre[i] != r) { j = pre[i]; pre[i] = r; i = j; } return pre[x]; } int main() { n = 0; while(scanf("%d%d", &a, &b) != EOF) { memset(v, 0, sizeof(v));//記錄所涉及的點 for(int i = 1; i <= N; i++) pre[i] = i; if(a < 0 && b < 0) break; else if(a == 0 && b == 0)//特殊處理, 空樹 { printf("Case %d is a tree.\n", ++n); continue; } pre[b] = a; v[a] = 1; v[b] = 1; mi = min(a, b); mx = max(a, b); flag = 1; while(scanf("%d%d", &a, &b) != EOF) { if(a == 0 && b == 0) break; if(mx < a || mx < b) mx = max(a, b); if(mi > a || mi > b) mi = min(a, b); v[a] = 1; v[b] = 1; if(flag == 1) { int fx = find(a); int fy = find(b); if((fy != b) || (fy == fx))//若構成環, 或孩子節點已經有父節點了, 那就是不合法的邊 flag = 0; else if(fy == b && fy != fx)//如果不構成環並且沒有父親節點, 那就是合法的, 加入 pre[b] = fx; } } int sum = 0; if(flag == 1) { for(int i = mi; i <= mx; i++)//判斷是否存在多棵樹 { if(v[i] == 1) { int fx = find(i); if(fx == i) { sum++; if(sum > 1) { flag = 0; break; } } } } } if(flag == 1) printf("Case %d is a tree.\n", ++n); else if(flag == 0) printf("Case %d is not a tree.\n", ++n); } return 0; } View Code

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved