PAT-ADVANCED1021——Deepest Root
阿新 • • 發佈:2018-11-06
我的PAT-ADVANCED程式碼倉:https://github.com/617076674/PAT-ADVANCED
原題連結:https://pintia.cn/problem-sets/994805342720868352/problems/994805482919673856
題目描述:
題目翻譯:
1021 最深的根
一張無環連通圖可以被看作是一棵樹。樹的高度取決於根節點的選取。現在你需要找出使得這棵樹最高的樹根。這樣的根稱作最深的根。
輸入格式:
每個輸入檔案包含一個測試用例。對每個測試用例,第一行有一個正整數N(<= 10000),代表節點數,這些節點編號為1 ~ N。接下來的N - 1行每行描述了一條連線兩節點的邊。
輸出格式:
對每個測試用例,在一行中輸出最深的根。如果該最深的根不唯一,按數字升序每行輸出一個根。如果所給的圖不是一棵樹,輸出Error: K components,K代表圖中的連通分量。
輸入樣例1:
5
1 2
1 3
1 4
2 5
輸出樣例1:
3
4
5
輸入樣例2:
5
1 3
1 4
2 5
3 4
輸出樣例2:
Error: 2 components
知識點:圖的深度優先遍歷、圖的廣度優先遍歷
思路:圖的深度優先遍歷+圖的廣度優先遍歷
先用圖的深度優先遍歷判斷圖是否可以看作一棵樹,即圖中有多少個連通分量。如果只有1個連通分量,則可以看作一棵樹。如果有1個以上的連通分量,就不能看作一棵樹。
對圖中的每個節點都進行廣度優先遍歷求其深度。
時間複雜度和空間複雜度均是O(N ^ 2)。
C++程式碼:
#include<iostream> #include<vector> #include<queue> using namespace std; struct node { int v; //節點編號 int level; //層數 node(int _v, int _level) : v(_v), level(_level) {}; //建構函式 }; int n; //節點個數 vector<int> graph[10001]; //無向圖 bool visited[10001] = {false}; //標記陣列 int level[10001] = {0}; //記錄廣度優先遍歷的層數 void dfs(int nowVisit); void bfs(int nowVisit, int index); int main() { cin >> n; int v1, v2; for(int i = 0; i < n - 1; i++) { cin >> v1 >> v2; graph[v1 - 1].push_back(v2 - 1); graph[v2 - 1].push_back(v1 - 1); } int count = 0; for(int i = 0; i < n; i++) { if(!visited[i]) { dfs(i); count++; } } if(count > 1) { printf("Error: %d components\n", count); return 0; } for(int i = 0; i < 10001; i++) { visited[i] = false; } for(int i = 0; i < n; i++) { for(int j = 0; j < 10001; j++) { visited[j] = false; } if(!visited[i]) { bfs(i, i); } } int max = level[0]; for(int i = 1; i < n; i++) { if(level[i] > max) { max = level[i]; } } for(int i = 0; i < n; i++) { if(level[i] == max) { cout << i + 1 << endl; } } return 0; } void dfs(int nowVisit) { visited[nowVisit] = true; for(int i = 0; i < graph[nowVisit].size(); i++) { if(!visited[graph[nowVisit][i]]) { dfs(graph[nowVisit][i]); } } } void bfs(int nowVisit, int index) { queue<node> q; q.push(node(nowVisit, 0)); visited[nowVisit] = true; while(!q.empty()) { node uNode = q.front(); if(uNode.level > level[index]) { level[index] = uNode.level; } int u = uNode.v; q.pop(); for(int i = 0; i < graph[u].size(); i++) { int v = graph[u][i]; if(!visited[v]) { q.push(node(v, uNode.level + 1)); visited[v] = true; } } } }
C++解題報告: