题干:
链接: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 ;
}