BZOJ1509: [NOI2003]逃学的小孩

1509: [NOI2003]逃学的小孩

这里写图片描写叙述
Input

第一行是两个整数N(3  N 
200000)和M,分别表示居住点总数和街道总数。

下面M行,每行给出一条街道的信息。

第i+1行包括整数Ui、Vi、Ti(1Ui, Vi 
N。1  Ti  1000000000),表示街道i连接居住点Ui和Vi,而且经过街道i需花费Ti分钟。街道信息不会反复给出。

Output

仅包括整数T。即最坏情况下Chris的父母须要花费T分钟才干找到Chris。

Sample Input

4 3

1 2 1

2 3 1

3 4 1

Sample Output
4

题解:

依照题意理解,找出3条路径a,b,c.(a>b>c)
答案就是(a+2*b+c)
树形dp,两次dfs
先以儿子dp。找出最大。中间,最小。
可是父亲所在的链也是一条链。所以须要第二次dfs,推断父亲所在的链。
代码:

/**************************************************************
    Problem: 1509
    User: wjyi
    Language: C++
    Result: Accepted
    Time:1188 ms
    Memory:13208 kb
****************************************************************/

#include<iostream>
#include<cstdio>
#include<cstring>
#define ll long long
using namespace std;
const int maxn=200005;
struct Node{
    int to,next,w;
}e[maxn<<1];
int tot,head[maxn],n,m;
ll mx1[maxn],mx2[maxn],mx3[maxn],f[maxn],ans;
bool vis[maxn];
void add(int u,int v,int w){
    e[++tot]=(Node){v,head[u],w};head[u]=tot;
}
void dfs(int x){
    vis[x]=1;mx1[x]=mx2[x]=0;
    for(int i=head[x];i;i=e[i].next)if(!vis[e[i].to]){
          dfs(e[i].to);
          mx3[x]=max(mx3[x],mx1[e[i].to]+e[i].w);
          if(mx3[x]>mx2[x])swap(mx3[x],mx2[x]);
          if(mx2[x]>mx1[x])swap(mx1[x],mx2[x]);
        }
}
void dfs1(int x){
    vis[x]=1;
    for(int i=head[x];i;i=e[i].next)
      if(!vis[e[i].to]){
        f[e[i].to]=f[x]+e[i].w;
        if(mx1[e[i].to]+e[i].w==mx1[x])
          f[e[i].to]=max(f[e[i].to],mx2[x]+e[i].w);
        else
          f[e[i].to]=max(f[e[i].to],mx1[x]+e[i].w);
        dfs1(e[i].to);
      }
}
void update(ll &x,ll &y,ll &z){
    if(y>x)swap(x,y);
    if(z>x)swap(x,z);
    if(z>y)swap(y,z);
    ans=max(ans,x+(y<<1)+z);
}
int main(){
    scanf("%d%d",&n,&m);
    int u,v,w;
    for(int i=1;i<=m;i++){
        scanf("%d%d%d",&u,&v,&w);
        add(u,v,w);add(v,u,w);
    }
    memset(vis,0,sizeof(vis));
    dfs(1);
    memset(vis,0,sizeof(vis));
    dfs1(1);
    ans=0;
    for(int i=1;i<=n;i++)
      f[i]<=mx3[i]?update(mx1[i],mx2[i],mx3[i]):update(mx1[i],mx2[i],f[i]);
    printf("%lld
",ans);
    return 0;
} 
原文地址:https://www.cnblogs.com/slgkaifa/p/7259874.html