- The Barycentre Of The Trees
For a multi-branch tree, if there is a node R with R as the root, and the largest sub-tree of all its sub-trees has the least number of nodes, the node R is said to be the center of gravity of the tree.
Now give you a multi-branch tree with n nodes. Find the center of gravity of this tree. If there are multiple centers of gravity, return the one with the lowest number.
x[i], y[i] represents the two points of the i-th edge.
Example
Example 1:
Given x = [1]
, y = [2]
, return 1
.
Input:
[1]
[2]
Output:
1
Explanation:
Both 1 and 2 can be center of gravity, but the number of 1 is the smallest.
Example 2:
Given x = [1,2,2]
, y = [2,3,4]
, return 2
.
Input:
[1,2,2]
[2,3,4]
Output:
2
Explanation:
2 is the center of gravity.
Notice
2 <= n <= 10^5
1 <= x[i], y[i] <= n
解法1:
这题是典型的树上的DP题。
思路:
- 先把无根树转有根树,建立tree数组,即A-B链接要建立A->B和B->A这两个链接。
- dfs()里面要注意对节点x遍历其子节点时,需要考虑子节点不能为x的父节点f,不然陷入死循环。
- 因为2)里面我们没有考虑x的父节点f,但实际上因为这是无联通图,x和f是双向链接,所以f也是x的子节点。所以还要考虑以f为节点的子节点数目,其为n - dp[x]。
class Solution {
public:
/**
* @param x: The vertexes of the edges
* @param y: The vertexes of the edges
* @return: Return the index of barycentre
*/
int getBarycentre(vector<int> &x, vector<int> &y) {
if (x.size() == 0) return 0;
n = x.size() + 1;
tree.resize(n + 1, vector<int>()); //same as tree.resize(n + 1)
dp.resize(n + 1); //dp[i] is the the sum of the children nodes under the tree with root i plus 1, dp[i] = sum(dp[j]) + 1;
for (int i = 0; i < x.size(); ++i) {
tree[x[i]].push_back(y[i]);
tree[y[i]].push_back(x[i]);
}
dfs(1, 0); //choose 1 as the root
return gChosenNode;
}
private:
vector<vector<int>> tree;
vector<int> dp;
int gMaxSubTreeSize = INT_MAX;
int gChosenNode = 0;
int n;
void dfs(int node, int father) {
int maxSubTreeSize = 0;
if (tree[node].size() == 0) {
dp[node] = 1; //leave node
} else {
for (int i = 0; i < tree[node].size(); ++i) {
int childNode = tree[node][i];
if ( childNode != father) { // prevent endless loop
dfs(childNode, node);
dp[node] += dp[childNode];
maxSubTreeSize = max(maxSubTreeSize, dp[childNode]);
}
}
dp[node] += 1; // add itself
}
maxSubTreeSize = max(maxSubTreeSize, n - dp[node]);
if (maxSubTreeSize < gMaxSubTreeSize || (maxSubTreeSize == gMaxSubTreeSize && node < gChosenNode)) {
gMaxSubTreeSize = maxSubTreeSize;
gChosenNode = node;
}
}
};