問題來源:hdu-3790
給你n個點,m條無向邊,每條邊都有長度d和花費p,給你起點s終點t,要求輸出起點到終點的最短距離及其花費,如果最短距離有多條路線,則輸出花費最少的。
Input
輸入n,m,點的編號是1~n,然後是m行,每行4個數 a,b,d,p,表示a和b之間有一條邊,且其長度爲d,花費爲p。最後一行是兩個數 s,t;起點s,終點。n和m爲0時輸入結束。
(1<n<=1000, 0<m<100000, s != t)
Output
輸出 一行有兩個數, 最短距離及其花費。
Sample Input
3 2
1 2 5 6
2 3 4 5
1 3
0 0
Sample Output
9 11
源代碼:
#include<stdio.h>
#include<string.h>
#define MAX 1006
#define INF 999999999
int map[MAX][MAX] , cost[MAX][MAX] , mark[MAX] , dis[MAX] , value[MAX];
//map[i][j]存儲雙向地圖,存儲i點到j點的距離
//cost[i][j]存儲i點到j點的花費
//mark[i]標誌i點手否被更新過
//dis[i]是i點到源點s的最短距離
//value[i]是i點到源點s的最短花費
void Dijstra( int map[][MAX] , int N , int s , int t );
int main( ){
int N , M;
int a , b , c , d , s , t;
while( ~scanf("%d%d",&N,&M) && N+M!=0 ){
for( int i=1 ; i<=N ; i++ )
for( int j=1 ; j<=N ; j++ ){
map[i][j] = cost[i][j] = INF; //輸入前初始化
map[i][i] = cost[i][i] = 0;
}
for( int i=1 ; i<=M ; i++ ){
scanf("%d%d%d%d",&a,&b,&c,&d);
if( c < map[a][b] ){ //重邊長度不等的情況
map[a][b] = map[b][a] = c;
cost[a][b] = cost[b][a] = d;
} //重邊相等長度的情況
else if( c==map[a][b] && d<cost[a][b] ){
cost[a][b] = cost[b][a] = d;
}
}
scanf("%d%d",&s,&t);
Dijstra(map,N,s,t);
}
return 0;
}
void Dijstra( int map[][MAX] , int N , int s , int t ){
//算法思路:最短路徑遞增,只適用於非負權邊
int min , k , last=s;
memset( mark , 0 , sizeof( mark ) );
for( int i=1 ; i<=N ; i++ ){
dis[i] = map[s][i];
value[i] = cost[s][i];
}
mark[s] = 1; //源點標記
while( 1 ){
for( int i=1 , min=INF ; i<=N ; i++ ){ //尋找下一個dis最短的點
if( mark[i]==0 && dis[i]<min ){
min = dis[k=i];
}
}
mark[k] = 1; //標記dis最短的邊
if( k==t ){
printf("%d %d\n",dis[t],value[t]);
return ;
}
for( int j=1 , min=INF ; j<=N ; j++ ){ //k點來鬆弛其他節點長度和花費
if( dis[k] + map[k][j] < dis[j] ){
dis[j] = dis[k] + map[k][j];
value[j] = value[k] + cost[k][j];
}
else if( dis[k]+map[k][j]==dis[j] && value[k]+cost[k][j]<value[j] ){
value[j] = value[k] + cost[k][j];
}
}
}
}
代碼分析:採用了Dijstra算法(求單源點到其他點的最短路徑),時間複雜度爲O(n^2),分爲三個步驟:尋找、標記、鬆弛。
Prim算法與Dijstra算法的區別:Prim是計算最小生成樹的算法、Dijkstra是計算最短路徑的算法;Prim算法的更新操作更新的cls是已訪問集合到未訪問集合中各點的距離;Dijkstra算法的更新操作更新的cls是源點到未訪問集合中各點的距離,已經訪問過的相當於已經找到源點到它的最短距離了;