牛客练习赛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\n",sum-ans);
   }
    return 0;
}
View Code

 

posted @ 2019-02-02 20:27  better46  阅读(660)  评论(0编辑  收藏  举报