zoukankan      html  css  js  c++  java
  • poj1849

    先翻译一下题面,这道题要我们用两个人去遍历树上的所有点,问我们最短距离。

    读完之后其实和前两天那题旅游非常像,我们要遍历一颗树上所有点,只要把所有边走两边然后减掉一条根到叶子的最长链就行了

    那么这道题有两个人一起走,所以就是减掉树的直径。

    问题转化到这里其实就非常好做了,树的直径我们可以用两边dfs和dp来做,这里我用的是dp,使用两个数组记录子树的最大长和次大长,加起来取个最大就行。

    下附代码:

     1 #include<cstdio>
     2 #include<iostream>
     3 #define ll long long
     4 using namespace std;
     5 ll res=0,head[100005],to[200005],Next[200005],len[200005],tot=0,f1[100005],f2[100005];
     6 int n,s;
     7 void add(int a,int b,int c){
     8     Next[tot]=head[a],to[tot]=b,len[tot]=c;
     9     head[a]=tot++;
    10 }
    11 void dfs(int x,int pre){
    12     ll ret=0;
    13     for (int i=head[x]; i!=-1; i=Next[i]){
    14         int v=to[i];
    15         if (v!=pre){
    16             dfs(v,x);
    17             if (f1[v]+len[i]>f1[x]){
    18                 f2[x]=f1[x];
    19                 f1[x]=f1[v]+len[i];
    20             }
    21             else f2[x]=max(f2[x],f1[v]+len[i]);
    22         }
    23     }
    24     res=max(res,f1[x]+f2[x]);
    25 }
    26 int main(){
    27     scanf("%d%d",&n,&s);
    28     for (int i=1; i<=n; i++) head[i]=-1;
    29     int sum=0;
    30     for (int i=1; i<n; i++){
    31         int a,b,c;
    32         scanf("%d%d%d",&a,&b,&c);
    33         add(a,b,c);
    34         add(b,a,c);
    35         sum+=c;
    36     }
    37     dfs(s,-1);
    38     printf("%lld",sum*2-res);
    39     return 0;
    40 }
    View Code
  • 相关阅读:
    3月工作问题总结
    【读书笔记】linux编程艺术
    项目管理工具 Trac入门
    [node.js]开放平台接口调用测试
    mysql 高并发更新计数问题
    memcache 问题 socket or its streams already null in trueClose call
    hadoop学习笔记
    node.js学习与应用
    mc参数备忘&javajson备忘
    WCF技术剖析_学习笔记之三
  • 原文地址:https://www.cnblogs.com/i-caigou-TT/p/13865304.html
Copyright © 2011-2022 走看看