鏈接:https://www.nowcoder.com/acm/contest/188/C
來源:牛客網
題目描述
小w不會離散數學,所以她van的圖論游戲是送分的
小w有一張n個點n-1條邊的無向聯通圖,每個點編號為1~n,每條邊都有一個長度
小w現在在點x上
她想知道從點x出發經過每個點至少一次,最少需要走多少路
小w現在在點x上
她想知道從點x出發經過每個點至少一次,最少需要走多少路
輸入描述:
第一行兩個整數 n,m,代表點數,和小w所處的位置
第二到第n行,每行三個整數 u,v,w,表示u和v之間有一條長為w的道路
輸出描述:
一個數表示答案
備注:
1 ≤ n ≤ 50000 , 1 ≤ w ≤ 2147483647
分析:我們可以直接把這個場景看成一個樹,則為了讓樹的每個節點都走到,我們在從根(起點)走到最底部之后,勢必要返回根,走另一個子樹,只有最后一個子樹不需要返回,則為了讓總路徑最小,我們只需要讓最后一個子樹為路徑最大的那個即可
注:之前很少使用vector,這次可以好好熟悉一下。
代碼如下:
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 struct node{ 5 int to,d; 6 node(int a,int b){ 7 to=a,d=b; 8 } 9 }; 10 ll ans; 11 vector<node>v[50010]; 12 bool vis[50010]; 13 void dfs(int s,ll dis){//dfs只能遍歷一次 14 vis[s]=1; 15 int size=v[s].size(); 16 if(size==1&&vis[v[s][0].to]){ 17 ans=max(ans,dis); 18 return ; 19 } 20 for(int i=0;i<size;i++) 21 if(!vis[v[s][i].to]) dfs(v[s][i].to,v[s][i].d+dis); 22 } 23 int main(){ 24 int n,x,a,b,c; 25 ll sum=0; 26 scanf("%d%d",&n,&x); 27 for(int i=1;i<n;i++){ 28 scanf("%d%d%d",&a,&b,&c); 29 v[a].push_back(node(b,c)); 30 v[b].push_back(node(a,c)); 31 sum+=c; 32 } 33 dfs(x,0); 34 printf("%lld\n",2*sum-ans); 35 return 0; 36 }