zoukankan      html  css  js  c++  java
  • Computer HDU

    Computer HDU - 2196

    题意:求以树上任一点为端点的最长链。注意,读入的不是边表,而是每个节点(除了1号,它是根节点)的父亲和与父亲间边的长度。

    方法:

    从每个端点出发的最长链,第一种是向下(向子节点)走,第二种是向父节点走。分别处理即可。(具体看程序)

    (感觉做法一点也不优美....最长链次长链什么鬼...)

    错误(本地):少了23行,没有将原来最长链更新到次长链上

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 using namespace std;
     5 struct Edge
     6 {
     7     int to,next,w;
     8 }e[20100];
     9 int f1[10100],ne,fa[10100],a1[10100],a2[10100],b1[10100],ww[10100],b2[10100],ansu[10100];
    10 //a1[i],b1[i]分别记录节点i向下最长链的长度,节点i向下最长链所经过的i的子节点编号
    11 //a2[i],b2[i]分别记录节点i向下次长链的长度(保证除了节点i以外,不与最长链有公共节点),节点i向下次长链所经过的自身的子节点编号
    12 //ww[i]记录节点i到父节点的边的权值
    13 //ansu[i]记录节点i向上走的最长链
    14 int n;
    15 void dfs(int x,int fa)
    16 {
    17     for(int k=f1[x];k!=0;k=e[k].next)
    18         if(e[k].to!=fa)
    19         {
    20             dfs(e[k].to,x);//先求出子节点向下的a1,b1,a2,b2,再用子节点的来更新自身的
    21             if(a1[e[k].to]+e[k].w>a1[x])//如果比已知最长链长
    22             {
    23                 a2[x]=a1[x],b2[x]=b1[x];//那么新的次长链就是已知最长链
    24                 a1[x]=a1[e[k].to]+e[k].w,b1[x]=e[k].to;//新的最长链就是自身指向这个子节点的边再加上子节点向下的最长链形成的链
    25             }
    26             else if(a1[e[k].to]+e[k].w>a2[x])//如果不比已知最长链长,但比已知次长链长
    27                 a2[x]=a1[e[k].to]+e[k].w,b2[x]=e[k].to;//新的次长链就是自身指向这个子节点的边再加上子节点向下的最长链形成的链
    28         }
    29 }
    30 void dfs2(int x,int fa)//分别为当前节点编号和当前节点父亲编号
    31 {
    32     if(fa!=0)//如果为根节点,那么没有向上的链,否则就有
    33     {
    34         int t1;
    35         if(x==b1[fa])
    36             t1=a2[fa];
    37         else
    38             t1=a1[fa];//t1表示父亲节点向下的最长链长度。如果父亲节点向下的最长链经过x,那么t1变为父亲节点向下的次长链长度
    39             //就是父亲节点的向下的不经过x的最长链长度
    40         ansu[x]=max(t1,ansu[fa])+ww[x];
    41         //当前节点向上的最长链,就是当前节点指向父亲的边再加上父亲节点向上的最长链形成的链,与当前节点指向父亲的边加上t1形成的链,其中较长的一条
    42     }
    43     for(int k=f1[x];k!=0;k=e[k].next)
    44         if(e[k].to!=fa)
    45             dfs2(e[k].to,x);//这一次要先求出父节点的才能求出子节点的,与第一个dfs()不一样
    46 }
    47 int main()
    48 {
    49     int i,x,y;
    50     while(scanf("%d",&n)==1)
    51     {
    52         ne=0;
    53         memset(f1,0,sizeof(f1));
    54         memset(fa,0,sizeof(fa));
    55         memset(a1,0,sizeof(a1));
    56         memset(a2,0,sizeof(a2));
    57         memset(ansu,0,sizeof(ansu));
    58         for(i=2;i<=n;i++)
    59         {
    60             scanf("%d%d",&x,&y);
    61             e[++ne].to=x;
    62             e[ne].next=f1[i];
    63             e[ne].w=y;
    64             f1[i]=ne;
    65             e[++ne].to=i;
    66             e[ne].next=f1[x];
    67             e[ne].w=y;
    68             f1[x]=ne;
    69             ww[i]=y;
    70         }
    71         dfs(1,0);//求出所有节点向下走的最长链与次长链
    72         dfs2(1,0);//求出所有节点向上走的最长链
    73         for(i=1;i<=n;i++)
    74             printf("%d
    ",max(a1[i],ansu[i]));//最后答案就是某个点向下、向上走的最长链中较长的一条
    75     }
    76     
    77     return 0;
    78 }
  • 相关阅读:
    MyEclipse 2015 Stable 2.0破解方法
    GeoGlobe Server运维
    GeoGlobe Server运维
    Silverlight用户无法注册之MySql.Data.dll不一致
    Photoshop影像匀色技术
    GeoGlobe Server使用问题收集
    Windows Server 2008 R2中无法使用360免费Wifi的解决方案
    吉奥平台软件安装经验分享
    U盘中毒后变为快捷方式的解决方法
    主机访问虚拟机中新建的网站
  • 原文地址:https://www.cnblogs.com/hehe54321/p/hdu-2196.html
Copyright © 2011-2022 走看看