遍历整个图的最短路径问题

链接:https://www.nowcoder.com/acm/contest/188/C
来源:牛客网

题目描述

小w不会离散数学,所以她van的图论游戏是送分的
小w有一张n个点n-1条边的无向联通图,每个点编号为1~n,每条边都有一个长度
小w现在在点x上
她想知道从点x出发经过每个点至少一次,最少需要走多少路

输入描述:

第一行两个整数 n,m,代表点数,和小w所处的位置
第二到第n行,每行三个整数 u,v,w,表示u和v之间有一条长为w的道路

输出描述:

一个数表示答案
示例1

输入

复制
3 1
1 2 1
2 3 1

输出

复制
2

备注:

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
",2*sum-ans);
35     return 0;
36 }
原文地址:https://www.cnblogs.com/qingjiuling/p/9688476.html