说明
大雪履盖了整个城市,市政府要求冬季服务部门尽快将一些街道(列在一份清单中)的积雪清除掉以恢复交通,整个城市由许多交叉路口和街道构成,当然任意两个交叉路口都是直接或间接连通的,清单给出了最少的街道,使得这些街道的积雪清除后任意两个交叉路口之间有且仅有一条通路,冬季服务部门只有两辆铲雪车及两名司机,他们的出发点位于某个交叉路口。
无论街道上有没有积雪,铲雪车每前进一米都要消耗一升燃料,冬季服务部门要求司机在铲除清单上的所有街道的积雪的前提下,要求消耗燃料最少,积雪铲完后车可以停在任意的交叉路口。
输入格式
输入文件的第一行包含两个整数N和S,1≤N≤100000,1≤S≤N。N为交叉路口的总数;S为铲雪车出发的路口序号。路口的标号为1••N。
接下来的N-1行为清单上的街道,每一行包含三个用空格隔开的整数A、B、C,表示一条从交叉路口A到交叉路口B的街道,C为该街道的长度,单位为米,1≤C≤1000。
输出格式
输出文件仅一行包含一个整数表示清除所有积雪所需的最少的燃料数量。
样例
输入数据 1
4 1
1 2 3
1 3 7
2 4 4
输出数据 1
14
这个题目类似与扫雪系列,只是由一辆车变成了两辆,先找到这棵树的直径,然后把所有的街道的和乘以2减去该数的直径就OK了。
就相当与把一辆车走的还要折返来的最长的那一段路让第二辆车去走。
#include <bits/stdc++.h>
using namespace std;
#define int long long
int s,n,a,b,c,h[1000001],vtx[1000001],nxt[1000001],bq[1000001],ans,cd[1000001],t,eg,maxn,maxp,kl;
char r;
void dfs(int beg,int fa,int nw)
{
cd[beg] = nw;
for(int i = h[beg]; i; i = nxt[i])
if(vtx[i] != fa)
dfs(vtx[i],beg,nw + bq[i]);
}
void adeg(int u,int v,int w)
{
eg++;
nxt[eg] = h[u];
h[u] = eg;
vtx[eg] = v;
bq[eg] = w;
}
signed main()
{
cin>>n>>s;
for(int i = 1; i < n; i++)
{
cin>>a>>b>>c;
adeg(a,b,c);
adeg(b,a,c);
kl += c;
}
kl *= 2;
dfs(s,0,0);
for(int i = 1; i <= n; i++)
if(maxn < cd[i])
{
maxn = cd[i];
maxp = i;
}
dfs(maxp,0,0);
maxn = maxp = 0;
for(int i = 1;i <= n;i++)
if(maxn < cd[i])
{
maxn = cd[i];
maxp = i;
}
kl -= maxn;
cout<<kl;
return 0;
}