1. 程式人生 > >《旅遊規劃》之dijkstra演算法

《旅遊規劃》之dijkstra演算法

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
const int N=500;
const int INF = 500;
int map[N+1][N+1][2];
int cost[N+1],dist[N];
int visited[N+1];
void dijkstra();
int main(){
	int n,m,s,d;
	cin>>n>>m>>s>>d;
	for(int i=0;i<n;i++){
		for(int j=0;j<n;j++){
			map[i][j][0] = INF;
			map[i][j][1] = INF;
			map[j][i][0] = INF;
			map[j][i][1] = INF;
		}
	} //初始化所有的路線和油費為INF
	for(int i=0;i<m;i++){
		int x,y,g,h;
		cin>>x>>y>>g>>h;
		map[x][y][0] = g;
		map[y][x][0] = g;
		map[x][y][1] = h;
		map[y][x][1] = h;
	} //寫入兩點之間的路線和油費,如果沒有的話就還是INF。
	for(int i=0;i<n;i++){
		visited[i] = 0; //標記是否訪問過
		dist[i] = map[s][i][0];
		cost[i] = map[s][i][1];
	} //因為題目要求是從s到d的結點,所以可以求出s到每個結點的最短距離,然後用dist[d],cost[d] 就可以輸出答案。
	//因為求s---d 所以初始化s為訪問過,且到s--s的距離為0
	visited[s] = 1;
	dist[s] = 0;
	dist[n] = INF; 
	cost[s] = 0;
	while(1){
		int v = n;
		//從未訪問的且與s有邊的結點中尋找最小值。
		for(int i=0;i<n;i++){
         	if(dist[i]<dist[v]&&visited[i]==0){
         		v = i;
         	}
		}
		if(v==n) break; // 如果v==n表示沒有找到最小的距離,就退出
		visited[v] = 1; 
		for(int w=0;w<n;w++){
			if(visited[w]==0&&map[v][w][0]<INF){
				//如果s--v+v--w的距離<s--w的距離,則就更新s---w的值,取小的
				if(map[v][w][0]+dist[v]<dist[w]){
					dist[w] = map[v][w][0] + dist[v];
					cost[w] = map[v][w][1] + cost[v];
				}
				//如果路徑相等,就比較錢數
				else if(map[v][w][0]+dist[v]==dist[w]&&cost[w]>=map[v][w][1]+cost[v]){
					cost[w] = cost[v] + map[v][w][1];
				}
			}
		} 
	}
	if(dist[d]<INF)
	cout<<dist[d]<<" "<<cost[d]<<endl;
	return 0;
}