牛客练习赛27-----C.水图(DFS求最长路径)
Posted ITAK
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了牛客练习赛27-----C.水图(DFS求最长路径)相关的知识,希望对你有一定的参考价值。
传送门
链接:https://www.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
解题思路:
通过观察(yy)发现,从
x
x
x 点出发,每条边都走了两遍,只有一条路径走了一遍,那么我们只需要找到一条最长的路径,那么就是总的边权和减去最长路径的边权和就行了。现在问题就是找到权值最长的路径,那么我们就直接
v
e
c
t
o
r
vector
vector 建边,然后
d
f
s
dfs
dfs 找最长路径即可。
代码如下:
#include <iostream>
#include <string.h>
#include <algorithm>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <vector>
using namespace std;
typedef long long LL;
const int MAXN = 50005;
struct Edge
int nxt;
LL w;
Edge(int a, LL b)
nxt = a;
w = b;
;
vector<Edge> g[MAXN];
bool vis[MAXN];
LL sum = 0;
void dfs(int x, LL w)
if(vis[g[x][0].nxt] && g[x].size()==1)//叶子节点且都已经访问过节点
sum = max(sum, w);
return ;
vis[x] = 1;
for(int i=0; i<g[x].size(); i++) if(!vis[g[x][i].nxt]) dfs(g[x][i].nxt, w+g[x][i].w);
int main()
int n, x; cin>>n>>x;
LL ans = 0;
for(int i=0; i<n-1; i++)
int u, v; LL w; cin>>u>>v>>w;
g[u].push_back(Edge(v, w));
g[v].push_back(Edge(u, w));
ans += w;
sum = 0;
dfs(x, 0);
cout<<ans*2-sum<<endl;
return 0;
与50位技术专家面对面
20年技术见证,附赠技术全景图
以上是关于牛客练习赛27-----C.水图(DFS求最长路径)的主要内容,如果未能解决你的问题,请参考以下文章