BZOJ 1131 [POI2008]Sta(树形DP)
【题目链接】 http://www.lydsy.com/JudgeOnline/problem.php?id=1131
【题目大意】
给出一个N个点的树,找出一个点来,以这个点为根的树时,所有点的深度之和最大
【题解】
我们记dp[i]为所有点到i的深度之和,我们发现对于定根树,
dp[x]=dp[fx]+n-2*size[x],那么我们随意定根,先算出dp[root],
递归计算每个dp[x],对于计算每个节点的不同链时,回溯消除链上影响。
【代码】
#include <cstdio>
#include <vector>
using namespace std;
const int N=1000010;
typedef long long LL;
vector<int> v[N];
int size[N],pos,n;
LL ans,res;
void dfs(int x,int d,int fx){
res+=d; size[x]=1;
for(int i=0;i<v[x].size();i++)if(fx!=v[x][i]){
dfs(v[x][i],d+1,x);
size[x]+=size[v[x][i]];
}
}
void dfs2(int x,int fx){
for(int i=0;i<v[x].size();i++)if(fx!=v[x][i]){
int y=v[x][i];
res=res+n-2*size[y];
if(res>ans||res==ans&&y<pos){
pos=y;
ans=res;
}dfs2(y,x);
res=res-(n-2*size[y]);
}
}
int main(){
while(~scanf("%d",&n)){
res=ans=0;
for(int i=1;i<n;i++){
int x,y;
scanf("%d%d",&x,&y);
v[x].push_back(y);
v[y].push_back(x);
}dfs(1,0,0);
ans=res;pos=1;
dfs2(1,0);
printf("%d\n",pos);
}return 0;
}
愿你出走半生,归来仍是少年

浙公网安备 33010602011771号