这个题的看一眼有点像树形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;
}
八倍经验