CCF習題 201612-4 交通規劃 (Dijkstra + 貪心)
阿新 • • 發佈:2018-12-24
大體題意:
題意不說了 中文的= =
思路:
既然要求到1的最短距離要存在,我們先用dijkstra演算法求出每一個點到1位置的最短距離,然後在看要哪一些邊!
既然要求路最短 並且包括最短距離,那麼我們可以列舉每一條邊{u,v,w}當這條路就是v到1位置的最短路之一時,我們就把這條邊的權值和已經儲存的最小權值進行比較!
這樣的貪心方法想一想 是很合理的!
我們貪心的要 每一個點最短路上的最小值,那麼最後的答案肯定是合理的,在聯通方面,既然每一個點都要找出一個邊,那麼你無論怎麼走,他都是聯通的!
詳細見程式碼:
#include <cstdio> #include <cstring> #include <algorithm> #include <vector> #include <queue> using namespace std; const int maxn = 10000 + 10; const int inf = 0x3f3f3f3f; struct edge{ int u, v, w; edge(int u = 0,int v = 0,int w = 0):u(u),v(v),w(w){} }; struct Node{ int d, u; Node(int d = 0, int u = 0):d(d),u(u){} bool operator < (const Node & rhs) const { return d > rhs.d; } }; priority_queue<Node> q; int ans[maxn]; struct Dijkstra{ int n, m; bool vis[maxn]; vector<edge> edges; vector<int>G[maxn]; int d[maxn]; void init(int n){ edges.clear(); for (int i = 0; i < maxn; ++i)G[i].clear(); this->n = n; m = 0; memset(vis,0,sizeof vis); } void addegde(int u,int v,int w){ edges.push_back(edge(u,v,w)); G[u].push_back(m++); } void Go(int s){ memset(d,inf,sizeof d); d[s] = 0; while(!q.empty())q.pop(); q.push(Node(0,s)); while(!q.empty()){ Node x = q.top(); q.pop(); int u = x.u; if (vis[u])continue; vis[u] = 1; for (int i = 0; i < G[u].size(); ++i){ edge& e = edges[G[u][i]]; if (d[e.v] > d[e.u] + e.w){ d[e.v] = d[e.u] + e.w; q.push(Node(d[e.v],e.v)); } } } } }dij; int main(){ int n,m; scanf("%d %d",&n, &m); dij.init(n); memset(ans,inf,sizeof ans); for (int i = 0; i < m; ++i){ int u, v, w; scanf("%d %d %d",&u, &v, &w); dij.addegde(u,v,w); dij.addegde(v,u,w); } dij.Go(1); for (int i = 1; i <= n; ++i){ for (int j = 0; j < dij.G[i].size(); ++j){ int u,v,w; u = dij.edges[dij.G[i][j]].u; v = dij.edges[dij.G[i][j]].v; w = dij.edges[dij.G[i][j]].w; if (dij.d[u] + w == dij.d[v]){ ans[v] = min(ans[v],w); } } } // printf("^^^ %d\n",dij.d[4]); int sum = 0; for (int i = 2; i <= n; ++i) sum += ans[i]; printf("%d\n",sum); return 0; }
問題描述
試題編號: | 201612-4 |
試題名稱: | 交通規劃 |
時間限制: | 1.0s |
記憶體限制: | 256.0MB |
問題描述: |
問題描述
G國國王來中國參觀後,被中國的高速鐵路深深的震撼,決定為自己的國家也建設一個高速鐵路系統。 建設高速鐵路投入非常大,為了節約建設成本,G國國王決定不新建鐵路,而是將已有的鐵路改造成高速鐵路。現在,請你為G國國王提供一個方案,將現有的一部分鐵路改造成高速鐵路,使得任何兩個城市間都可以通過高速鐵路到達,而且從所有城市乘坐高速鐵路到首都的最短路程和原來一樣長。請你告訴G國國王在這些條件下最少要改造多長的鐵路。 輸入格式 輸入的第一行包含兩個整數n, m,分別表示G國城市的數量和城市間鐵路的數量。所有的城市由1到n編號,首都為1號。 接下來m行,每行三個整數a, b, c,表示城市a和城市b之間有一條長度為c的雙向鐵路。這條鐵路不會經過a和b以外的城市。 輸出格式 輸出一行,表示在滿足條件的情況下最少要改造的鐵路長度。 樣例輸入 4 5 1 2 4 1 3 5 2 3 2 2 4 3 3 4 2 樣例輸出 11 評測用例規模與約定 對於20%的評測用例,1 ≤ n ≤ 10,1 ≤ m ≤ 50; 對於50%的評測用例,1 ≤ n ≤ 100,1 ≤ m ≤ 5000; 對於80%的評測用例,1 ≤ n ≤ 1000,1 ≤ m ≤ 50000; 對於100%的評測用例,1 ≤ n ≤ 10000,1 ≤ m ≤ 100000,1 ≤ a, b ≤ n,1 ≤ c ≤ 1000。輸入保證每個城市都可以通過鐵路達到首都。 |