PAT 資料結構 06-圖5. 旅遊規劃dijkstra演算法
阿新 • • 發佈:2018-12-13
題意:
有了一張自駕旅遊路線圖,你會知道城市間的高速公路長度、以及該公路要收取的過路費。現在需要你寫一個程式,幫助前來諮詢的遊客找一條出發地和目的地之間的最短路徑。如果有若干條路徑都是最短的,那麼需要輸出最便宜的一條路徑。
輸入:
4 5 0 3 0 1 1 20 1 3 2 30 0 3 4 10 0 2 2 20 2 3 1 20
輸出:
3 40
題解:
#include<bits/stdc++.h> using namespace std; #define MAXN 505 #define INFINITY 505 struct City { int len; int fees; }; int N; //城市的個數 編號 0 ~ (N - 1) int M; //高速公路的條數 int S; //出發地的城市編號 int D; //目的城市編號 City city[MAXN][MAXN]; //圖 int flag[MAXN]; //標記 City dist[MAXN]; //dist表示 這個點到原點的最短路徑 int Length; //路徑長度 int Fees; //收費額 void init() { for(int i = 0; i < N; ++i) { for(int j = 0; j < N; ++j) { city[i][j].len = INFINITY; city[i][j].fees = INFINITY; } } for(int i = 0; i < N; ++i) { dist[i].len = INFINITY; dist[i].fees = INFINITY; } } void setDistValue(int s, int i, int j) { dist[S].len = i; dist[S].fees = j; } int findMinDist() { City minDist; minDist.fees = INFINITY; minDist.len = INFINITY; int V; //用於返回的頂點 for(int i = 0; i < N; ++i) { if(flag[i] == 0) {//找到與之最短距離的點; if(dist[i].len < minDist.len) { minDist.len = dist[i].len; minDist.fees = dist[i].fees; V = i; } else if(dist[i].len == minDist.len) { if(dist[i].fees < minDist.fees) minDist.fees = dist[i].fees; } } } if(minDist.len < INFINITY) return V; //返回對應的頂點下標 else return -1; //這樣的頂點不存在,返回錯誤標記 } void dijkstra() { setDistValue(S, 0, 0); //將起點S吃入集合 flag[S] = 1; //標記 for(int i = 0 ; i < N; ++i) { dist[i].len = city[S][i].len; dist[i].fees = city[S][i].fees; }//初始化; int V; //用來表示頂點下標 while(1) { V = findMinDist();//仔細理解一下這個點; if(V == -1) //這樣結點不存在 break; flag[V] = 1; //吃入 for(int i = 0; i < N; ++i) //對圖中的每個頂點 { if(flag[i] == 0 && city[V][i].len < INFINITY) // W是V的鄰邊且未被吃入 { if(city[V][i].len < 0) //為負邊 return ; //不能正確處理,返回錯誤標記 if(dist[V].len + city[V][i].len < dist[i].len) //吃入V使得dist[i]變小 { dist[i].len = dist[V].len + city[V][i].len; dist[i].fees = dist[V].fees + city[V][i].fees; } else if(dist[V].len + city[V][i].len == dist[i].len) //吃入V等於dist[i] { if(dist[V].fees + city[V][i].fees < dist[i].fees) //路費比其少則更新 dist[i].fees = dist[V].fees + city[V][i].fees; } } } } } int main() { scanf("%d%d%d%d", &N, &M, &S, &D); init(); //初始化 int beginCity; int endCity; int len; int fees; for(int i = 0; i < M; ++i) { scanf("%d%d%d%d", &beginCity, &endCity, &len, &fees); city[beginCity][endCity].len = len; city[beginCity][endCity].fees = fees; city[endCity][beginCity].len = len; city[endCity][beginCity].fees = fees; //路是雙向的; } dijkstra(); printf("%d %d", dist[D].len, dist[D].fees); return 0; }