链接
思路:
重链走一次,轻链走两次
用spfa求出该点到所有点的路径(也就是说所有的链的权值已经求出来)
求出来后减去这些路径中的最大值即可
/* 链式前向星SPFA最短路算法*/
#include<iostream>
#include<queue>
#include <algorithm>
#include <stdio.h>
#include<cstring>
#define LL long long
using namespace std ;
const int maxn = 10050 ;
int N, M, head[maxn] ;
LL dis[maxn], cnt;
int vis[10500] ;
int n , m ;
struct Edge
{ LL cap ;
int v, next; // v 是去向 , cap 是流量(权值) next就不解释了
}e[100000];
void init()
{
cnt = 0;
memset(head, -1, sizeof (head));
memset(dis , 0x3f , sizeof(dis)) ;
}
void Addedge(int x, int y, LL z)
{
e[cnt].v = y;
e[cnt].cap = z;
e[cnt].next = head[x];
head[x] = cnt++;
}
void spfa(int s){
dis[s] = 0 ;
queue<int> q ;
q.push(s) ;
while(!q.empty()){
int u = q.front() ; q.pop() ;
vis[u] = 0 ;
for(int i = head[u] ; i != -1 ; i = e[i].next){
int v = e[i].v ;
LL w = e[i].cap ;
if(dis[v] > w + dis[u] ) {
dis[v] = w + dis[u] ;
if(!vis[v]) { vis[v] = 1 ; q.push(v) ;}
}
}
}
}
int main(){
cin >> n >> m ; // n个节点的树 , m为起点
init() ;
LL ans = 0 ;
memset(vis , 0 , sizeof(vis) ) ;
for(int i = 0 ; i < n-1 ; i++){
int u , v ; LL w ;
cin >> u >> v >>w ;
ans += w*2 ;
Addedge(u , v , w) ;
Addedge(v , u , w) ;
}
spfa(m) ; LL maxn = 0 ;
// cout << "ans = " << ans << endl ;
for(int i = 1 ; i <= n ; i++){
maxn = max(maxn , dis[i]) ;
// cout << dis[i] << endl ;
}
cout << ans - maxn << endl ;
return 0 ;
}