牛客練習賽27 水圖(最短路 or dfs)
阿新 • • 發佈:2018-12-13
題目描述
小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; }