Descriptionsios
Mercer國王是ACM王國的王者。他的王國裏有一個首都和一些城市。使人驚訝的是,如今王國沒有道路。最近,他計劃在首都和城市之間修建道路,但事實證實他的計劃的建設成本遠高於預期。算法
爲了下降成本,他決定經過從原計劃中刪除一些道路來制定新的施工計劃。可是,他認爲新計劃應知足如下條件:數組
許多計劃可能符合上述條件,但King Mercer但願以最低成本瞭解該計劃。您的任務是編寫一個程序,該程序讀取其原始計劃並以最低成本計算新計劃的成本。spa
輸入.net
輸入包含多個數據集。每一個數據集的格式以下。code
N M
u1 v1 d1 c1
.
.
.
uM vM dM cM blog
每一個數據集的第一行開始於兩個整數,Ñ和中號(1≤ Ñ ≤10000,0≤ 中號 ≤20000)。N和M分別表示原始計劃中的城市數量和道路數量。ip
如下M行描述了原始計劃中的道路信息。在我個行包含四個整數 ui,v i,d i和ci(1≤ ui,vi ≤ N,ui ≠ v i,1≤ di ≤1000,1≤ ci ≤1000 )。ui,v i,d i和ci代表有是鏈接道路ui個城市和v i個城市,其長度爲d i和它的成本須要建設ci。ci
每條道路都是雙向的。沒有兩條道路鏈接同一對城市。第一城市是王國的首都。get
輸入的結尾由包含兩個由空格分隔的零的線表示。您不該將該行做爲數據集處理。
輸出
對於每一個數據集,打印知足一行條件的計劃的最低成本。
樣本輸入
3 3 1 2 1 2 2 3 2 1 3 1 3 2 5 5 1 2 2 2 2 3 1 1 1 4 1 1 4 5 1 1 5 3 1 1 5 10 1 2 32 10 1 3 43 43 1 4 12 52 1 5 84 23 2 3 58 42 2 4 86 99 2 5 57 83 3 4 11 32 3 5 75 21 4 5 23 43 5 10 1 2 1 53 1 3 1 65 1 4 1 24 1 5 1 76 2 3 1 19 2 4 1 46 2 5 1 25 3 4 1 13 3 5 1 65 4 5 1 34 0 0
樣本輸入的輸出
3 5 137 218
題目連接
https://vjudge.net/problem/Aizu-2249
求出城市1到各個城市之間的最短距離,同時算出城市1到各個城市之間的最低花費
10003Floyd顯然會超時,並且這裏沒負數,Dijkstra算法再好不過了,下面我寫的Dijkstra算法改了一下,用的二維數組d[i][j],能夠求出i到j的最短距離,雖然在這沒什麼用,可是用之後確定用的到,這個能夠直接拿來用,這個模板能夠copy一下
AC代碼
#include <iostream> #include <cstdio> #include <fstream> #include <algorithm> #include <cmath> #include <deque> #include <vector> #include <queue> #include <string>1 #include <cstring> #include <map> #include <stack> #include <set> #include <sstream> #define IOS ios_base::sync_with_stdio(0); cin.tie(0) #define Mod 1000000007 #define eps 1e-6 #define ll long long #define INF 0x3f3f3f3f #define MEM(x,y) memset(x,y,sizeof(x)) #define Maxn 20000+5 #define P pair<int,int>//first最短路徑second頂點編號 using namespace std; int N,M; struct edge { int to,dis,cost; edge(int to,int dis,int cost):to(to),dis(dis),cost(cost) {} }; vector<edge>G[Maxn];//G[i] 從i到G[i].to的距離爲dis,花費的錢爲cost int d[Maxn][Maxn];//d[i][j]從i到j的最短距離 int sum[Maxn];//sum[i],起點到i之間所須要的花費的錢 void Dijk(int s) { priority_queue<P,vector<P>,greater<P> >q;//按first從小到大出隊 for(int i=0; i<=N; i++) d[s][i]=INF; d[s][s]=0; q.push(P(0,s)); while(!q.empty()) { P p=q.top(); q.pop(); int v=p.second;//點v if(d[s][v]<p.first) continue; for(int i=0; i<G[v].size(); i++) { edge e=G[v][i];//枚舉與v相鄰的點 if(d[s][e.to]>=d[s][v]+e.dis) { if(d[s][e.to]==d[s][v]+e.dis)//距離相等,比較誰花費的錢少 sum[e.to]=min(sum[e.to],e.cost); else//若d[s][e.to]>d[s][v]+e.dis,相求出最短距離,再求出最短距離所須要的錢 sum[e.to]=e.cost; d[s][e.to]=d[s][v]+e.dis; q.push(P(d[s][e.to],e.to)); } } } } int main() { IOS; while(cin>>N>>M,N+M) { MEM(sum,0); for(int i=1; i<=N; i++) G[i].clear(); for(int i=0; i<M; i++) { int u,v,d,c; cin>>u>>v>>d>>c; G[u].push_back(edge(v,d,c)); G[v].push_back(edge(u,d,c)); } Dijk(1);//城市1到各個城市的最短距離 int ans=0; for(int i=2; i<=N; i++) ans+=sum[i]; cout<<ans<<endl; } return 0; }