1. 程式人生 > >PAT-ADVANCED1021——Deepest Root

PAT-ADVANCED1021——Deepest Root

我的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++解題報告: