洛谷 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)
\(\rmoustache 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 
#include 
#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'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

2018.5.24

转载于:https://www.cnblogs.com/butterflydew/p/9083162.html

你可能感兴趣的:(洛谷 P4408 逃学的小孩 解题报告)