牛客练习赛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求最长路径)的主要内容,如果未能解决你的问题,请参考以下文章

牛客练习赛84 E牛客推荐系统开发之标签重复度

牛客练习-凤凰——不同寻常的最短路(找规律求结点数)

牛客练习赛1 树 dp + dfs序

牛客网Nowcoder 牛客练习赛13 A.幸运数字Ⅰ B.幸运数字Ⅱ(数组或者dfs) C.幸运数字Ⅲ(思维)

牛客练习赛88 D都市的柏油路太硬

牛客练习赛30 C 小K的疑惑(01分类+搜索)