小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
基本思想:设想这是一棵树,从根出发想要走遍所有的节点,一定会从分叉处返回,最后一条分叉不必返回,所以我们可以找出最长的一条分叉路径,然后用2倍的路径总长-最长的分叉路径即得可以走遍所有节点的最短路径。
代码如下:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
struct node
{
int nex,d;
node(int a,int b)
{
nex = a,d = b;
}
};
vector<node>v[50010];
bool vis[50010];
ll ans;
void dfs(int s,ll dis)
{
vis[s] = 1;//标记已访问的节点
int size = v[s].size();
if(size == 1 && vis[v[s][0].nex])//度数为1且与它相连的节点已访问
{
ans = max(ans,dis);
return ;
}
for(int i = 0;i < size;i ++)
if(!vis[v[s][i].nex])//与它相连的节点未访问
dfs(v[s][i].nex,dis + v[s][i].d);
}
int main()
{
int n,x,u,k,w;
ll sum = 0;
while(cin >> n >> x)
{
for(int i = 1;i < n;i ++)
{
cin >> u >> k >> w;
v[u].push_back(node(k,w));
v[k].push_back(node(u,w));
sum += w;
}
dfs(x,0);//x为起点,0为初始距离
cout << 2 * sum - ans << endl;
}
return 0;
}