【Aizu - 2249】Road Construction(最短路 Dijkstra算法)

Road Construction

Descriptionsios

Mercer國王是ACM王國的王者。他的王國裏有一個首都和一些城市。使人驚訝的是,如今王國沒有道路。最近,他計劃在首都和城市之間修建道路,但事實證實他的計劃的建設成本遠高於預期。算法

爲了下降成本,他決定經過從原計劃中刪除一些道路來制定新的施工計劃。可是,他認爲新計劃應知足如下條件:數組

  • 對於每對城市,都有一條鏈接它們的路線(一組道路)。
  • 首都和每一個城市之間的最小距離不會改變他原來的計劃。

許多計劃可能符合上述條件,但King Mercer但願以最低成本瞭解該計劃。您的任務是編寫一個程序,該程序讀取其原始計劃並以最低成本計算新計劃的成本。spa

輸入.net

輸入包含多個數據集。每一個數據集的格式以下。code

N M
u1 v1 d1 c1 
.
.
.
uM vM dM cM blog

每一個數據集的第一行開始於兩個整數,Ñ中號(1≤ Ñ ≤10000,0≤ 中號 ≤20000)。NM分別表示原始計劃中的城市數量和道路數量。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和它的成本須要建設cici

每條道路都是雙向的。沒有兩條道路鏈接同一對城市。第一城市是王國的首都。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;
}
相關文章
相關標籤/搜索