Description
For example, consider the tree:
Deleting node 4 yields two trees whose member nodes are {5} and {1,2,3,6,7}. The larger of these two trees has five nodes, thus the balance of node 4 is five. Deleting node 1 yields a forest of three trees of equal size: {2,6}, {3,7}, and {4,5}. Each of these trees has two nodes, so the balance of node 1 is two.
For each input tree, calculate the node that has the minimum balance. If multiple nodes have equal balance, output the one with the lowest number.
Input
Output
Sample Input
1 7 2 6 1 2 1 4 4 5 3 7 3 1
Sample Output
1 2
思路 |
题意大意:若断开某结点,求出它的分结点的和的最大值,再求出断开每个节点结界点的最小值。 思路:DFS,将每个节点遍历一遍,求出它的子树结点的最大值。用一数组记录每个节点子树的最大值。 (一直都怕深搜的题,勇敢,不要怕他) |
源码 |
#include<stdio.h> #include<string.h> #include<iostream> #include<vector> #include<algorithm> #define INF 0xfffffff using namespace std; vector<int>v[20005]; int visit[20005]; int rem[20005]; int dp[20005], n; void dfs(int tt) { int i, len=v[tt].size(); visit[1]=1; for(i=0; i<len; i++) { if(!visit[v[tt][i]]) { visit[v[tt][i]]=1; dfs(v[tt][i]); } } for(i=0; i<v[tt].size(); i++) dp[tt]+=dp[v[tt][i]]; dp[tt]++; int sum=0; rem[tt]=0; for(i=0; i<v[tt].size(); i++) { sum+=dp[v[tt][i]]; rem[tt]=max(rem[tt], dp[v[tt][i]]); } rem[tt]=max(rem[tt], n-sum-1); return ; } int main() { int i, j, T, a, b; scanf("%d", &T); while(T--) { scanf("%d", &n); for(i=0; i<=n; i++) v[i].clear(); for(i=0; i<n-1; i++) { scanf("%d%d", &a, &b); v[a].push_back(b); v[b].push_back(a); } memset(visit, 0, sizeof(visit)); memset(rem, 0, sizeof(rem)); memset(dp, 0, sizeof(dp)); dfs(1); int big=INF, root; for(i=1; i<=n; i++) if(big>rem[i]) { big=rem[i]; root=i; } printf("%d %d\n", root, big); } } |