AOJ 2249 Road Construction (dijkstra)
阿新 • • 發佈:2017-08-19
() pla ble func esp nal dijk writer 減少
某國王需要修路,王國有一個首都和多個城市,需要修路。已經有修路計劃了,但是修路費用太高。
為了減少修路費用,國王決定從計劃中去掉一些路,但是需要滿足一下兩點:
- 保證所有城市都能連通
- 所有城市到首都的最短路不變
思路:
在Dijkstra找最短路的時候,就記錄一下費用
if(d[e.to] > d[v] + e.dist) { ... prev_min_cost[e.to] = e.cost; // 最短路必經之路,則費用也必須要 } else if(d[e.to] == d[v] + e.dist) // 最短路可選擇之路,選擇最小的費用連接 prev_min_cost[e.to] = min(prev_min_cost[e.to], e.cost);
程序
#include <iostream> #include <queue> #include <functional> #include <cstring> using namespace std; struct edge { int to, dist, cost; edge(int to, int dist, int cost) : to(to), dist(dist), cost(cost) {} bool operator<(const edge &b) const { return dist > b.dist; } }; vector<edge> G[10005]; int N, M; // 節點數,道路數 int d[10005]; // 距離源點s(s==1)的最小距離 int prev_min_cost[10005]; // 節點的鄰接邊最小花費 int ans; void dijkstra(int s) { memset(d, 0x3f, sizeof(d)); memset(prev_min_cost, 0x3f, sizeof(prev_min_cost)); d[s] = 0; priority_queue<edge> que; que.push(edge(s, d[s], 0)); while (!que.empty()) { edge p = que.top(); que.pop(); int v = p.to; if (d[v] < p.dist) continue; for (int i = 0; i<G[v].size(); ++i) { edge e = G[v][i]; if (d[e.to] > d[v] + e.dist) { d[e.to] = d[v] + e.dist; que.push(edge(e.to, d[e.to], G[v][i].cost)); prev_min_cost[e.to] = e.cost; // 最短路必經之路,則費用也必須要 } else if (d[e.to] == d[v] + e.dist) // 最短路可選擇之路,選擇最小的費用連接 prev_min_cost[e.to] = min(prev_min_cost[e.to], e.cost); } } } void solve() { dijkstra(1); for (int u = 2; u <= N; ++u) ans += prev_min_cost[u]; // 求出所有必須的費用(n-1條邊) cout << ans << endl; } int main() { int u, v, d, c; while (cin >> N >> M) { for (int u = 1; u <= N; ++u) G[u].clear(); ans = 0; if (N == M && N == 0) break; for (int i = 0; i < M; ++i) { cin >> u >> v >> d >> c; G[u].push_back(edge(v, d, c)); // 構圖 G[v].push_back(edge(u, d, c)); } solve(); } return 0; }
AOJ 2249 Road Construction (dijkstra)