1131: [POI2008]Sta

来源:互联网 发布:知我药妆 知乎 编辑:程序博客网 时间:2024/06/05 08:18

题目链接

题目大意:给出一个N个点的树,找出一个点来,以这个点为根的树时,所有点的深度之和最大

题解:比较反套路的树形dp,自顶向下更新答案
首先dfs得到以1为根的答案
考虑将选择的点由1移动到1的儿子v
有size[v]个点dep-1,(n-size[v])个点dep+1

f[v]=f[x]+n2size[v]

我的收获:树形dp的顺序

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cstdlib>#include <vector>#include <ctime>#include <cmath>using namespace std;const int M=1000005;#define INF 0x7fffffffint n;int t,head[M];int dep[M],size[M];long long f[M];struct edge{int to,nex;}e[M<<1];void add(int u,int v){e[t].to=v,e[t].nex=head[u],head[u]=t++;}int read(){    int x=0,f=1;char c=getchar();    while(c>'9'||c<'0') {if(c=='-') f=-1;c=getchar();}    while(c<='9'&&c>='0') x=x*10+c-48,c=getchar();    return x*f;}void dfs(int x,int fa){    size[x]=1;f[x]=dep[x];    for(int i=head[x];i!=-1;i=e[i].nex){        int v=e[i].to;        if(v==fa) continue;        dep[v]=dep[x]+1,dfs(v,x);        size[x]+=size[v],f[x]+=f[v];    }}void dfsans(int x,int fa){    for(int i=head[x];i!=-1;i=e[i].nex){        int v=e[i].to;        if(v==fa) continue;        f[v]=f[x]+n-2*size[v];        dfsans(v,x);    }}void work(){    dfs(1,0);dfsans(1,0);    int root=0;    for(int i=1;i<=n;i++) if(f[i]>f[root]) root=i;    cout<<root<<endl;}void init(){    n=read();int x,y;    memset(head,-1,sizeof(head));    for(int i=1;i<n;i++) x=read(),y=read(),add(x,y),add(y,x);}int main(){    init();    work();    return 0;}
原创粉丝点击