BZOJ 1509: [NOI2003]逃学的小孩

题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1509

直接求出树的直径,枚举每个点更新一遍答案。

#include<cstring>
#include<iostream>
#include<algorithm>
#include<cstdio>
#define maxn 200500
#define rep(i,l,r) for (int i=l;i<=r;i++)
#define down(i,l,r) for (int i=l;i>=r;i--)
#define clr(x,y) memset(x,y,sizeof(x))
#define eps 1e-8
#define ll long long
#define mm 999911659
using namespace std;
struct data{int obj,pre; ll c;
}e[maxn*2];
int head[maxn],tot,s,t,n,m;
ll dis[maxn],dis2[maxn],dis3[maxn],ans;
ll read(){
    ll x=0,f=1; char ch=getchar();
    while (!isdigit(ch)){if (ch=='-') f=-1; ch=getchar();}
    while (isdigit(ch)) {x=x*10+ch-'0'; ch=getchar();}
    return x*f;
}
void insert(int x,int y,ll z){
    e[++tot].obj=y; e[tot].pre=head[x]; e[tot].c=z; head[x]=tot; 
}
void dfs(int u,int fa){
    for (int j=head[u];j;j=e[j].pre){
        int v=e[j].obj;
        if (v!=fa){
            dis[v]=dis[u]+e[j].c;
            if (dis[v]>dis[s])  s=v;
            dfs(v,u);
        }
    }
}
void dfs2(int u,int fa){
    for (int j=head[u];j;j=e[j].pre){
        int v=e[j].obj;
        if (v!=fa){
            dis2[v]=dis2[u]+e[j].c;
            if (dis2[v]>dis2[t]) t=v;
            dfs2(v,u);
        }
    }
}
void dfs3(int u,int fa){
    for (int j=head[u];j;j=e[j].pre){
        int v=e[j].obj;
        if (v!=fa){
            dis3[v]=dis3[u]+e[j].c;
            ans=max(ans,min(dis3[v],dis2[v])+dis2[t]);
            dfs3(v,u);
        }
    }
}
int main(){
    n=read(); m=read();
    rep(i,1,m){
        int x=read(),y=read();
        ll z=read();
        insert(x,y,z); insert(y,x,z);
    }
    dfs(1,0);
    dfs2(s,0);
    dfs3(t,0);
    printf("%lld\n",ans);
    return 0;
}

 

posted on 2016-01-07 19:37  ctlchild  阅读(240)  评论(0编辑  收藏  举报

导航