遍历整个图的最短路径问题
链接: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 }