原題:
https://cses.fi/problemset/task/1131
題意:
給一棵 n 點樹(無根、無權),輸出樹的直徑長度(兩點間最長路徑的邊數)。
解題思路:
#include <bits/stdc++.h>
using namespace std;
pair<int,int> farthest(int src, const vector<vector<int>>& g){
int n = g.size() - 1;
vector<int> dist(n+1, -1);
queue<int> q;
dist[src] = 0; q.push(src);
int best = src;
while(!q.empty()){
int u = q.front(); q.pop();
if(dist[u] > dist[best]) best = u;
for(int v: g[u]){
if(dist[v] == -1){
dist[v] = dist[u] + 1;
q.push(v);
}
}
}
return {best, dist[best]};
}
int main(){
ios::sync_with_stdio(false); cin.tie(nullptr);
int n; if(!(cin>>n)) return 0;
vector<vector<int>> g(n+1);
for(int i=0;i<n-1;i++){
int u,v; cin>>u>>v;
g[u].push_back(v); g[v].push_back(u);
}
auto [a,_] = farthest(1, g);
auto [b,diam] = farthest(a, g);
cout << diam << "\n";
return 0;
}
原題:
https://cses.fi/problemset/task/1132
題意:
給一棵 n 點樹,對每個節點 v,輸出它到樹上最遠節點的距離。
解題思路:
#include <bits/stdc++.h>
using namespace std;
vector<int> bfs(int src, const vector<vector<int>>& g){
int n = g.size()-1;
vector<int> dist(n+1, -1);
queue<int> q; dist[src]=0; q.push(src);
while(!q.empty()){
int u=q.front(); q.pop();
for(int v: g[u]) if(dist[v]==-1){
dist[v]=dist[u]+1; q.push(v);
}
}
return dist;
}
int main(){
ios::sync_with_stdio(false); cin.tie(nullptr);
int n; if(!(cin>>n)) return 0;
vector<vector<int>> g(n+1);
for(int i=0;i<n-1;i++){
int u,v; cin>>u>>v;
g[u].push_back(v); g[v].push_back(u);
}
// 找直徑兩端
auto d1 = bfs(1, g);
int a = 1;
for(int i=1;i<=n;i++) if(d1[i] > d1[a]) a = i;
auto dA = bfs(a, g);
int b = a;
for(int i=1;i<=n;i++) if(dA[i] > dA[b]) b = i;
auto dB = bfs(b, g);
for(int i=1;i<=n;i++){
cout << max(dA[i], dB[i]) << (i==n?'\n':' ');
}
return 0;
}
原題:
https://leetcode.com/problems/maximum-depth-of-binary-tree/description/
題意:
給二元樹根節點 root,回傳樹的最大深度(根到最遠葉子的節點數)。
解題思路:
/**
* Definition for a binary tree node.
* struct TreeNode { int val; TreeNode *left; TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *l, TreeNode *r) : val(x), left(l), right(r) {}
* };
*/
class Solution {
public:
int maxDepth(TreeNode* root) {
if(!root) return 0;
return 1 + max(maxDepth(root->left), maxDepth(root->right));
}
};
原題:
https://leetcode.com/problems/diameter-of-binary-tree/description/
題意:
給二元樹根節點 root,回傳直徑長度(任兩節點間最長路徑的邊數)。
解題思路:
class Solution {
int best = 0;
int height(TreeNode* node){
if(!node) return 0;
int L = height(node->left);
int R = height(node->right);
best = max(best, L + R); // 經過此節點的路徑
return 1 + max(L, R);
}
public:
int diameterOfBinaryTree(TreeNode* root) {
height(root);
return best;
}
};