链接:https://www.nowcoder.com/acm/contest/188/C
来源:牛客网
小w不会离散数学,所以她van的图论游戏是送分的
小w有一张n个点n-1条边的无向联通图,每个点编号为1~n,每条边都有一个长度
小w现在在点x上
她想知道从点x出发经过每个点至少一次,最少需要走多少路
输入描述:
第一行两个整数 n,x,代表点数,和小w所处的位置
第二到第n行,每行三个整数 u,v,w,表示u和v之间有一条长为w的道路
输出描述:
一个数表示答案
示例1
输入
复制
3 1
1 2 1
2 3 1
输出
复制
2
备注:
1 ≤ n ≤ 50000 , 1 ≤ w ≤ 2147483647
题目的意思很简单就是让你一次性跑完所有的点然后求算一下,这个人要走的最短距离,讲过画几个图之后会发现,mindis=所有边权和的二倍然后减掉最长的那条边就是答案,因为你要跑完所有的边所以就会有些边一定要跑两次,有一些边不需要跑两次,因为我们想要我们的距离跑的最短吗,所以就是我们让那一条最长的边就跑一次就是我们我们要的最优解了;
#include <bits/stdc++.h>
using namespace std;
const int Max = 1e6+10;
typedef long long ll;
#define rep(i,s,n) for(ll i=s;i<=n;i++)
#define per(i,n,s) for(ll i=n;i>=s;i--)
struct node{
ll u,v,w,next;
}Edge[Max<<1];
ll head[Max],sum,max1,n,s,to,dis[Max];
bool visited[Max];
void add(ll u, ll v, ll w){
Edge[to].v=v;
Edge[to].w=w;
Edge[to].next=head[u];
Edge[to].u=u;
head[u]=to++;
}
ll q[Max];
void spfa(){
visited[s]=true;
int front1=0,rearl=0;
q[rearl++]=s;
while(rearl>front1){
ll u=q[front1++];
for(int i=head[u];i!=-1;i=Edge[i].next){
int v=Edge[i].v;
if(dis[v]<dis[u]+Edge[i].w&&!visited[v]){
dis[v]=dis[u]+Edge[i].w;
if(dis[v]>max1) {
max1=dis[v];
}
if(!visited[v]){
q[rearl++]=v;
visited[v]=true;
}
}
}
}
}
int main(){
scanf("%lld %lld",&n,&s);
rep(i,0,n) head[i]=-1;
rep(i,1,n-1){
ll u,v,w;
scanf("%lld %lld %lld",&u,&v,&w);
add(u,v,w);
add(v,u,w);
sum+=w;
}
max1=0;
spfa();
printf("%lld\n",sum*2-max1);
}