zoukankan      html  css  js  c++  java
  • 洛谷 P4408 逃学的小孩 解题报告

    P4408 [NOI2003]逃学的小孩

    题目描述

    Chris家的电话铃响起了,里面传出了Chris的老师焦急的声音:“喂,是Chris的家长吗?你们的孩子又没来上课,不想参加考试了吗?”一听说要考试,Chris的父母就心急如焚,他们决定在尽量短的时间内找到Chris。他们告诉Chris的老师:“根据以往的经验,Chris现在必然躲在朋友Shermie或Yashiro家里偷玩《拳皇》游戏。现在,我们就从家出发去找Chris,一但找到,我们立刻给您打电话。”说完砰的一声把电话挂了。

    Chris居住的城市由N个居住点和若干条连接居住点的双向街道组成,经过街道x需花费Tx分钟。可以保证,任两个居住点间有且仅有一条通路。Chris家在点C,Shermie和Yashiro分别住在点A和点B。Chris的老师和Chris的父母都有城市地图,但Chris的父母知道点A、B、C的具体位置而Chris的老师不知。

    为了尽快找到Chris,Chris的父母会遵守以下两条规则:

    如果A距离C比B距离C近,那么Chris的父母先去Shermie家寻找Chris,如果找不到,Chris的父母再去Yashiro家;反之亦然。
    Chris的父母总沿着两点间唯一的通路行走。
    显然,Chris的老师知道Chris的父母在寻找Chris的过程中会遵守以上两条规则,但由于他并不知道A,B,C的具体位置,所以现在他希望你告诉他,最坏情况下Chris的父母要耗费多长时间才能找到Chris?

    输入输出格式

    输入格式:

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

    以下(M)行,每行给出一条街道的信息。第(i+1)行包含整数(U_i)(V_i)(T_i) ((1≤U_i, V_i ≤ N,1 ≤ T_i ≤ 1000000000)),表示街道i连接居住点(U_i)(V_i),并且经过街道(i)需花费(T_i)分钟。街道信息不会重复给出。

    输出格式:

    输出文件仅包含整数T,即最坏情况下Chris的父母需要花费(T)分钟才能找到Chris。


    我仍未具有将问题很好抽象出模型的能力,所以哪怕大家都说水,我也想到了利用树的直径来贪心的时候,我依旧写爆了这个题。

    (lmoustache E(C,A)+E(A,B),A,B,C in G,E(C,A)<E(C,B))
    ( moustache E(C,B)+E(B,A),A,B,C in G,E(C,A)>E(C,B))

    模型即为求解以上的最大值。

    我们关注两条链如何分别取到最大值。

    对于(E_1(C,A))(E_2(C,B)),我们发现,对任意点(C)(E_1),(E_2)一定是距离它最远和次远的两个点。

    这是什么,就是树的直径的两个端点啊。(求解树的直径以及这是为什么可以看看NOIP2007”树网的核”或者SDOI2011”消防”)

    此时另一条链恰好不就是取到了自己的最大值?

    那么枚举直径外每个点就好了。


    code(代码真的丑QAQ·):

    #include <cstdio>
    #include <cstring>
    #define ll long long
    const int N=200010;
    ll max(ll x,ll y) {return x>y?x:y;}
    ll min(ll x,ll y) {return x<y?x:y;}
    struct Edge
    {
        ll next,to,w;
    }edge[N*2];
    
    ll read()
    {
        ll x=0;char c=getchar();
        while(c<'0'||c>'9') c=getchar();
        while(c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}
        return x;
    }
    
    int head[N],cnt=0;
    void add(ll u,ll v,ll w)
    {
        edge[++cnt].next=head[u];edge[cnt].to=v;edge[cnt].w=w;head[u]=cnt;
    }
    ll n,m;
    int used[N];
    int l,r;
    ll m_max=0;
    void f_dfs(ll now,ll ww)
    {
        used[now]=1;
        if(m_max<ww)
        {
            m_max=ww;
            l=now;
        }
        for(int i=head[now];i;i=edge[i].next)
        {
            ll v=edge[i].to,w=edge[i].w;
            if(!used[v])
                f_dfs(v,w+ww);
        }
    }
    
    ll ge_dfs(ll now)
    {
        used[now]=1;
        ll m_max=0;
        for(int i=head[now];i;i=edge[i].next)
        {
            ll v=edge[i].to,w=edge[i].w;
            if(!used[v])
                m_max=max(ge_dfs(v)+w,m_max);
        }
        return m_max;
    }
    
    int flag=1;
    ll f[N],w0[N],f0[N];
    void b_dfs(ll now)
    {
        used[now]=1;
        if(now==r)
            flag=0;
        for(int i=head[now];i;i=edge[i].next)
        {
            ll v=edge[i].to,w=edge[i].w;
            if(!used[v]&&flag)
            {
                b_dfs(v);
                if(!flag)
                {
                    f[v]=now;
                    w0[v]=w;
                }
            }
        }
    }
    ll ans=0;
    ll g[N],cnt0=0;
    int main()
    {
        n=read(),m=read();
        ll u,v,w;
        for(int i=1;i<=m;i++)
        {
            u=read(),v=read(),w=read();
            add(u,v,w);
            add(v,u,w);
        }
        f_dfs(1,0);//求端点
        r=l;
        m_max=0;
        memset(used,0,sizeof(used));
        f_dfs(r,0);//求端点
        memset(used,0,sizeof(used));
        b_dfs(l);//构建链
        memset(used,0,sizeof(used));
        int now=r;
        while(now)
        {
            used[now]=1;
            g[++cnt0]=now;
            now=f[now];
        }
        for(int i=1;i<=cnt0;i++)
            f0[i]=f0[i-1]+w0[g[i-1]];
        for(int i=1;i<=cnt0;i++)
            ans=max(ans,ge_dfs(g[i])+min(f0[i],f0[cnt0]-f0[i]));
        printf("%lld
    ",ans+f0[cnt0]);
        return 0;
    }
    

    2018.5.24

  • 相关阅读:
    P1541 乌龟棋 暴力DP
    HDU
    HDU-6608 Fansblog 数论 ,威尔逊定理,快速乘
    P3842 [TJOI2007]线段 思维 ,DP
    模板 BSGS
    Gym
    HDU
    HDU
    HDU
    P1095 守望者的逃离 暴力DP
  • 原文地址:https://www.cnblogs.com/butterflydew/p/9083162.html
Copyright © 2011-2022 走看看