bzoj 1131: [POI2008]Sta 树形dp

来源:互联网 发布:linux 查看文件多少行 编辑:程序博客网 时间:2024/06/07 04:01

题意

给出一个N个点的树,找出一个点来,以这个点为根的树时,所有点的深度之和最大
n<=1000000

分析

刷道水题压压惊先。。。
只要先求出以1为根的深度和,然后每次换根的时候算一下深度的变化就好了。

代码

#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>using namespace std;typedef long long LL;const int N=1000005;int ans,n,cnt,last[N],size[N];LL tot,mx;struct edge{int to,next;}e[N*2];int read(){    int x=0,f=1;char ch=getchar();    while (ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}    while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}    return x*f;}void addedge(int u,int v){    e[++cnt].to=v;e[cnt].next=last[u];last[u]=cnt;    e[++cnt].to=u;e[cnt].next=last[v];last[v]=cnt;}void dfs(int x,int fa,int dep){    size[x]=1;tot+=dep;    for (int i=last[x];i;i=e[i].next)    {        if (e[i].to==fa) continue;        dfs(e[i].to,x,dep+1);        size[x]+=size[e[i].to];    }}void dp(int x,int fa,LL now){    if (now>mx||now==mx&&x<ans) mx=now,ans=x;    for (int i=last[x];i;i=e[i].next)    {        if (e[i].to==fa) continue;        dp(e[i].to,x,now+n-size[e[i].to]*2);    }}int main(){    n=read();    for (int i=1;i<n;i++)    {        int x=read(),y=read();        addedge(x,y);    }    dfs(1,0,1);    mx=tot;ans=1;    dp(1,0,tot);    printf("%d",ans);    return 0;}
原创粉丝点击