Description
大雪覆盖了整座城市,市政府要求“交通部门”尽快将一些街道(列在一份清单中)的积雪清除掉以恢复交通。整个城市由许多交叉路口和街道构成,当然任意两个交叉路口都是直接或间接连通的。清单给出了最少的街道,使得这些街道的积雪清除后任意两个交叉路口之间有且仅有一条通路。冬季交通部门只有一辆铲雪车和一名司机,这辆铲雪车的出发点位于某个交叉路口S。
无论街道上有没有积雪,铲雪车每前进一米都要消耗一升燃料。交通部门要求司机在铲除清单上的所有街道的积雪的前提下,消耗燃料最少,铲完后车可以停在任意交叉路口。
Input
第一行包含2个整数N,S(1<=S<=N),N 为交叉路口总数,路口的标号为1...N,S为铲雪车出发的路口序号。 接下来的N-1行为清单上的街道,每一行包含三个用空格隔开的整数A,B,C,表示一条从交叉路口A到交叉路口B的街道,C为该街道的长度(单位为米)。
Output
仅一行,包含一个整数,表示铲掉所有积雪所需的最少燃料。
Sample Input 1
5 1
1 2 8
1 3 10
3 4 10
4 5 7
Sample Output 1
43
Hint
20%的数据有:1<=N<=15;
100%的数据有:1<=N<=100000,1<=C<=1000。
按题意,街道就是棵树,每条边都要走来回共2遍,除了...
可以选择最后不回到根,因此肯定找条离根最远的叶子节点为最后一个节点,然后就停在这里不回去了,达到距离走的最小。
除此之外其他的路都要走2遍,因此主要就是考求离根最远的节点的距离。是个水题,完毕。
代码:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<queue>
#define maxn 100005
#define maxm 200005
using namespace std;
int fir[maxn],ne[maxm],to[maxm],w[maxm],np=0;
void add(int x,int y,int z){
ne[++np]=fir[x];
fir[x]=np;
to[np]=y;
w[np]=z;
}
int dfs(int u,int f){
int ans=0;
for(int i=fir[u];i;i=ne[i]){
int v=to[i];
if(v==f)continue;
int tmp=dfs(v,u)+w[i];
ans=max(ans,tmp);
}
return ans;
}
int main(){
int n,s;
scanf("%d%d",&n,&s);
int sum=0;
for(int i=1,x,y,z;i<n;i++){
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);add(y,x,z);
sum+=z;
}
printf("%d",sum*2-dfs(s,0));
return 0;
}