07-圖6 旅遊規劃 (25分)
阿新 • • 發佈:2018-12-30
有了一張自駕旅遊路線圖,你會知道城市間的高速公路長度、以及該公路要收取的過路費。現在需要你寫一個程式,幫助前來諮詢的遊客找一條出發地和目的地之間的最短路徑。如果有若干條路徑都是最短的,那麼需要輸出最便宜的一條路徑。
輸入格式:
輸入說明:輸入資料的第1行給出4個正整數N、M、S、D,其中N(2≤N≤500)是城市的個數,順便假設城市的編號為0~(N−1);M是高速公路的條數;S是出發地的城市編號;D是目的地的城市編號。隨後的M行中,每行給出一條高速公路的資訊,分別是:城市1、城市2、高速公路長度、收費額,中間用空格分開,數字均為整數且不超過500。輸入保證解的存在。
輸出格式:
在一行裡輸出路徑的長度和收費總額,數字間以空格分隔,輸出結尾不能有多餘空格。
輸入樣例:
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
題目的意思:就是求給定兩個城市,求這兩個城市的最短路徑。。。如果把城市看成圖的頂點和城市間的公路長度為頂點之間的權重的話。。那裡題目就變成了有權圖的最短路徑問題了。。而有權圖的最短問題問題最著名的就是Dijkstra演算法。。。在這道題目中,我們需要注意一下的是如果存在兩條相同的最短路徑的話,我們需要的是花費最小的那一條。因此,我們需要建立一個額外的陣列用來儲存路徑間的花費。
Talk is cheap, show me the code !
#include<iostream>
#include<vector>
using namespace std;
#define INT_MAX 65535
// 返回未收錄頂點中dist最小的那個頂點
int findMinDist(vector<int> dist, vector<int> collected)
{
int N = dist.size(); //頂點的個數
int minDist = INT_MAX, V = -1;
for (int i = 0; i < N; ++i) {
// 更新最小距離
if (!collected[i] && dist[i] < minDist) {
minDist = dist[i];
V = i;
}
}
return V; //返回最小路徑的那個頂點
}
void dijkstra(int s, int d, vector<vector<int>> roadLen,
vector<vector<int>> roadCost)
{
int N = roadLen[0].size();
vector<int> collected(N, false);
vector<int> path(N, -1);
vector<int> dist(N, 0);
vector<int> cost(N, 0);
// 初始化最短路徑陣列
for (int i = 0; i < N; ++i) {
// 如果沒有直通的邊,將其設為最大值
if(!roadLen[s][i]) {
dist[i] = cost[i] = INT_MAX;
} else {
dist[i] = roadLen[s][i];
cost[i] = roadCost[s][i];
}
}
// 首先將起始點s收入到集合中去
dist[s] = 0;
collected[s] = true;
while (1) {
// 找到最小路徑且未收錄的那個頂點
auto v = findMinDist(dist, collected);
if (v == -1) //表示這樣的頂點不存在
break;
collected[v] = true;
for (int w = 0; w < N; ++w) {
//v的沒有被收錄的鄰接頂點
if (!collected[w] && roadLen[v][w]) {
if (dist[v] + roadLen[v][w] < dist[w]) {
dist[w] = dist[v] + roadLen[v][w];
cost[w] = cost[v] + roadCost[v][w];
path[w] = v;
} else if (dist[v] + roadLen[v][w] == dist[w]
&& cost[v] + roadCost[v][w] < cost[w]) {
//dist[w] = dist[v] + roadLen[v][w];
cost[w] = cost[v] + roadCost[v][w];
//path[w] = v;
}
}
}
} // while
cout << dist[d] << " " << cost[d] << endl;
}
int main()
{
int N, M, S, D;
cin >> N >> M >> S >> D;
// 建立一個鄰接矩陣,如果邊不存在則用0表示
vector<vector<int>> roadLen(N, vector<int>(N, 0)), roadCost(N,vector<int>(N,0));
for (int i = 0; i < M; ++i) {
int beg, ed, len, cost;
cin >> beg >> ed >> len >> cost;
roadLen[beg][ed] = len;
roadLen[ed][beg] = len;
roadCost[beg][ed] = cost;
roadCost[ed][beg]= cost;
}
dijkstra(S, D, roadLen, roadCost);
return 0;
}