题干:

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

小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

备注:

1 ≤ n ≤ 50000 , 1 ≤ w ≤ 2147483647

解题报告:

  和   牛客369的C一样的思维。

AC代码:

#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#define ll long long
using namespace std;
const int MAX = 6e5 + 5 ; 
const int INF = 0x3f3f3f3f;
struct Node {
	int to;
	int w;
	int ne;
} e[MAX];
struct point {
	int pos,c;
	point(){}
	point(int pos,int c):pos(pos),c(c){}
 
};
int n;
int head[MAX];
int cnt = 0 ;
bool vis[MAX];
void init() {
	cnt = 0;
	memset(head,-1,sizeof(head));
}
void add(int u,int v,int w) {
	e[cnt].to = v;
	e[cnt].w = w;
	e[cnt].ne = head[u];
	head[u] = cnt;
	cnt++;  
} 
 
int bfs(int x,int &w) {
	queue <point> q;
	int maxx = 0;
	int retp = x ;//返回的点坐标 
	memset(vis,0,sizeof(vis) );
	q.push(point(x,0));vis[x] = 1;
	point now;
	while(q.size() ) {
		point cur = q.front();
		q.pop();
		for(int i = head[cur.pos]; i!=-1; i=e[i].ne) {
			if(vis[e[i].to]) continue;
			vis[e[i].to] = 1;
			now.pos = e[i].to;
			now.c = cur.c + e[i].w;
			if(now.c>maxx) {
				maxx = now.c;
				retp = now.pos;
			}
			q.push(now);
		}
		//w = maxx;
		
	}
	w = maxx;
	return retp;
}
int main()
{
    int x;
	cin>>n>>x;
	init();
	int u,v,w;
	ll sum = 0;
	for(int i = 1; i<=n-1; i++) {
		scanf("%d%d%d",&u,&v,&w);
		add(u,v,w);
		add(v,u,w);
		sum += w;
	}
	int ans1 = 0,ans2 = 0;
	u = bfs(x,ans1);
	//printf("ans2 = %d\n",ans2);
	printf("%lld\n",1LL*ans1 + (sum-ans1)*2);
	return 0 ;
}