zoukankan      html  css  js  c++  java
  • hdu 2196 (树形DP)

    求出每一点到所有点的最大距离,刚开始就有点想法求最长边的问题,但想了一会不知道怎么去把子节点转化成根节点。

    任选一点为根节点,先求出每个节点到子节点的最大距离和次大距离,然后更新每个子节点的最大,次大距离,就是把每个子节点当一次根节点,如果它在父节点的最大距离边上,就用次大距离+到父节点的距离与自己的最大次大距离比较,,,,






    #include<stdio.h>
    #include<string.h>
    #define N 10001
    int n,head[N],num,vis[N],dp[N][2];
    struct edge
    {
        int st,ed,next,w;
    }E[N*2];
    void addedge(int x,int y,int w)
    {
        E[num].st=x;
        E[num].ed=y;
        E[num].w=w;
        E[num].next=head[x];
        head[x]=num++;
    }
    int dfs(int u)
    {
        int i,v;
        vis[u]=1;
        for(i=head[u];i!=-1;i=E[i].next)
        {
            v=E[i].ed;
            if(vis[v]==1)continue;
            int temp=dfs(v)+E[i].w;
            if(temp>dp[u][1])//最长边
            {
                dp[u][0]=dp[u][1];
                dp[u][1]=temp;
            }
            else if(temp>dp[u][0])//次长边
            {
                dp[u][0]=temp;
            }
        }
        return dp[u][1]; 
    }
    void dfs1(int u)
    {
      vis[u]=1;
      int i,v,temp;
      for(i=head[u];i!=-1;i=E[i].next)
      {
          v=E[i].ed;
          if(vis[v]==1)continue;
          if(dp[v][1]+E[i].w==dp[u][1])//如果改点在父节点的最长边上,就与次长边比较
            temp=dp[u][0]+E[i].w;
          else temp=dp[u][1]+E[i].w;//不在父节点的最长边上,就与最长边比较
            if(temp>dp[v][1])
            {
                dp[v][0]=dp[v][1];
                dp[v][1]=temp;
            }
            else if(temp>dp[v][0])
            {
                dp[v][0]=temp;
            }
            dfs1(v);
      }
    }
    int main()
    {
        int i,x,y,w;
        while(scanf("%d",&n)!=-1)
        {
            memset(head,-1,sizeof(head));
            num=0;
            for(x=2;x<=n;x++)
            {
                scanf("%d%d",&y,&w);
                addedge(x,y,w);
                addedge(y,x,w);
            }
            memset(dp,0,sizeof(dp));
            memset(vis,0,sizeof(vis));
            dfs(1);
            memset(vis,0,sizeof(vis));
            dfs1(1);
             for(i=1;i<=n;i++)
                 printf("%d
    ",dp[i][0]>dp[i][1]?dp[i][0]:dp[i][1]);
        }
        return 0;
    }



  • 相关阅读:
    怎样用c/c++编程连接mysql数据库?
    c#中转义符总结
    制作文件系统出错运行mkubimagemlc2
    面试中常考的C函数库中的字符串处理函数
    移动支付模式再添新军:指纹支付
    面试中常考的单链表处理
    选购冰箱勿被概念迷惑:并非功能越多越好
    地址转换
    JavaScriptGarden/
    配置非安装版的mysql 5.5
  • 原文地址:https://www.cnblogs.com/riskyer/p/3228527.html
Copyright © 2011-2022 走看看