这个题的看一眼有点像树形dp,但是要怎么去优化我们转移方程呢
这是为什么呢,我们的树形dp很难考虑来之前的答案,那么d[y] 怎么办,我们可以先以1为根计算出以1为根的答案
#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
using namespace std;const int N = (int)5e4+5;
int n;
int e[N*2],ne[N*2],h[N],idx = 0;
int size[N],dp[N]; // size[i]用来记录以i为根的树的节点的数量
// dp[i] 记录以i为根的树的距离之和 int d[N]; // 记录以1为节点的距离 void add(int a,int b){e[++idx] = b, ne[idx] = h[a] , h[a] = idx;
}int dfs1(int u){size[u] = 1; // 先包括自己这个节点 for(int i=h[u];i;i=ne[i]){int to = e[i];if(d[to]) continue;d[to] = d[u] + 1;size[u] +=dfs1(to);}return size[u];
} void dfs(int u,int father){dp[u] = dp[father] + (n-size[u]) - size[u];for(int i=h[u];i;i=ne[i]){int to = e[i];if(to==father) continue;dfs(to,u);}
}int main(){cin >> n;for(int i=1;i<n;i++){int a,b;cin >> a >> b;add(a,b),add(b,a);}d[1] = 1;dfs1(1);for(int i=1;i<=n;i++) dp[1] += d[i];// 计算dp[1] -= n;for(int i=h[1];i;i=ne[i]){int to = e[i];dfs(to,1);} int ans = dp[1];int node = 1;for(int i=2;i<=n;i++){if(ans>dp[i]){node = i; ans = dp[i];}if(ans==dp[i]) node = min(node,i);}cout << node << " " << ans;return 0;
}
八倍经验