1. 程式人生 > >牛客練習賽27 水圖(最短路 or dfs)

牛客練習賽27 水圖(最短路 or 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

思路:答案就是每條邊的距離加起來乘以2減去最長的起點到其他點的最長的路徑。

dfs程式碼:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 5e4 + 5;
vector<pair<int, int>> mp[maxn];
int mlen;
void dfs(int x, int fa, int len)
{
    mlen = max(mlen, len);
    for(auto &it : mp[x])
    {
        if(it.first == fa) continue;
        dfs(it.first, x, it.second + len);
    }
}
int main()
{
    int n, x, u, v, w, sum = 0;
    cin >> n >> x;
    for(int i = 1; i < n; i++)
    {
        cin >> u >> v >> w;
        mp[u].push_back({v, w});
        mp[v].push_back({u, w});
        sum += w;
    }
    dfs(x, 0, 0);
    cout << sum * 2 - mlen << endl;
}

Dijkstra程式碼:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5;
int n, m;
int d[maxn];
vector<pair<int,int> >E[maxn];
void init()
{
    for(int i = 0; i < maxn; i++) d[i] = 1e9;
    for(int i = 0; i < maxn; i++) E[i].clear();
}
void Dijkstra()
{
    priority_queue<pair<int,int> >Q;
        Q.push(make_pair(-d[n],n));
        while(!Q.empty())
        {
            int now = Q.top().second;
            Q.pop();
            for(int j = 0; j < E[now].size(); j++)
            {
                int v = E[now][j].first;
                if(d[v] > d[now]+E[now][j].second)
                {
                    d[v] = d[now]+E[now][j].second;
                    Q.push(make_pair(-d[v],v));
                }
            }
        }
}
int main()
{
    while(cin >> m >> n && n+m)
    {
        init();
        int a, b, x, sum = 0;
        for(int i = 1; i < m; i++)
        {
            cin >> a >> b >> x;
            sum += x;
            E[a].push_back(make_pair(b,x));
            E[b].push_back(make_pair(a,x));
        }
        d[n] = 0; Dijkstra();
        int mx = -999;
        for(int i = 1; i <= m; i++)
            mx = max(mx, d[i]);
        printf("%d\n",sum*2-mx);
    }
    return 0;
}