Hdu 2196 Computer (树形dp)

来源:互联网 发布:小粉红 知乎 编辑:程序博客网 时间:2024/05/16 19:49

题目大意:

求出每一个结点距离叶子节点的最大距离。


思路分析:

假设1为树的根。

通过一遍dfs 可以求出每个节点到儿子节点上的叶子节点的最远距离。

然后我们要做的就是如果更新答案。

问题就是如果我们开始求的最大值本来就是一个儿子更新的,如果再深搜的话又会造成重复更新。

所以就记录两个值,最大值和次大值。

然后不断更新这两个值。


#include <cstdio>#include <iostream>#include <cstring>#include <algorithm>#define maxn 10005using namespace std;int head[maxn];int to[maxn<<1];int next[maxn<<1];int len[maxn<<1];int tot;void init(){    tot=0;    memset(head,0,sizeof head);}void addedge(int u,int v,int w){    tot++;    next[tot]=head[u];    to[tot]=v;    head[u]=tot;    len[tot]=w;}bool vis[maxn];int maxval[maxn],nex[maxn],maxid[maxn],nexid[maxn];//最大值        次大值   更新最大值的id  更新次大值的idvoid dfs(int x){    maxval[x]=nex[x]=0;    for(int p = head[x] ;p; p = next[p])    {        int v = to[p];        if(!vis[v])        {            vis[v]=true;            dfs(v);            if(nex[x]<maxval[v]+len[p])            {                nex[x]=maxval[v]+len[p];                nexid[x]=v;                if(nex[x]>maxval[x])                {                    swap(nex[x],maxval[x]);                    swap(nexid[x],maxid[x]);                }            }        }    }}void update(int x,int pre){    for(int p = head[x];p;p=next[p])    {        int v=to[p];        if(v==pre)continue;        if(v==maxid[x])        {            if(nex[x]+len[p]>nex[v])            {                nex[v]=nex[x]+len[p];                nexid[v]=x;                if(nex[v]>maxval[v])                {                    swap(nex[v],maxval[v]);                    swap(nexid[v],maxid[v]);                }            }        }        else {            if(maxval[x]+len[p]>nex[v])            {                nex[v]=maxval[x]+len[p];                nexid[v]=x;                if(nex[v]>maxval[v])                {                    swap(nex[v],maxval[v]);                    swap(nexid[v],maxid[v]);                }            }        }        update(v,x);    }}int main(){    int n;    while(scanf("%d",&n)!=EOF)    {        init();        for(int i=2;i<=n;i++)        {            int l,r;            scanf("%d%d",&l,&r);            addedge(i,l,r);            addedge(l,i,r);        }        memset(vis,false,sizeof vis);        vis[1]=true;        dfs(1);        update(1,-1);        for(int i=1;i<=n;i++)            printf("%d\n",maxval[i]);    }    return 0;}


0 0
原创粉丝点击