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