zoukankan      html  css  js  c++  java
  • 牛客练习赛27-----C.水图(DFS求最长路径)

    传送门


    来源:牛客网
    题目描述:
    小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

    思路:

    通过举例子我们可以看到,答案就是每条路径走了两遍,只有

    一条边权和最大的路径只走了一遍,现在问题就是找到权值最长的路径,

    那么我们就直接 建边,然后 dfs 找最长路径即可。


    原文来自:https://blog.csdn.net/qingshui23/article/details/82843391

    代码:

    //dfs找到权值最大的路径即可
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    #define maxn 50005
    int n,x;
    struct node
    {
        int to,cost;
    };
    vector<node>a[maxn];
    
    ll dfs(int x,int y)//x是终点,y是起点;目的是防止往回走
    {
        ll mx=0;
        for(int i=0;i<a[x].size();i++)
        {
            int j=a[x][i].to;
            ll sum=0;
            if(j!=y)
            {
              sum+=a[x][i].cost;
              sum+=dfs(j,x);
            }
            mx=max(mx,sum);
        }
        return mx;
    }
    int main()
    {
       while(~scanf("%d %d",&n,&x))
       {
           ll sum=0;
           for(int i=1;i<n;i++)
           {
               int u,v;
               ll c;
               scanf("%d %d %lld",&u,&v,&c);
               node tmp;
               tmp.to=v;
               tmp.cost=c;
               a[u].push_back(tmp);
               tmp.to=u;
               a[v].push_back(tmp);
               sum+=c*2;
           }
           ll ans=dfs(x,x);
           printf("%lld
    ",sum-ans);
       }
        return 0;
    }
    View Code
  • 相关阅读:
    leetcode5
    leetcode4
    maven笔记
    枚举使用笔记
    List遍历删除解决方案:遍历删除,迭代删除,removeIf
    java笔记(web部分)
    webview使用
    json数据格式+gson解析json问题总结
    android:layout_weight的简单使用
    欢迎界面效果
  • 原文地址:https://www.cnblogs.com/zhgyki/p/10349106.html
Copyright © 2011-2022 走看看