最短路徑問題(dijkstra,迪傑斯特拉演算法)
阿新 • • 發佈:2018-12-14
題目描述
給你n個點,m條無向邊,每條邊都有長度d和花費p,給你起點s終點t,要求輸出起點到終點的最短距離及其花費,如果最短距離有多條路線,則輸出花費最少的。輸入描述:
輸入n,m,點的編號是1~n,然後是m行,每行4個數 a,b,d,p,表示a和b之間有一條邊,且其長度為d,花費為p。最後一行是兩個數 s,t;起點s,終點t。n和m為0時輸入結束。 (1<n<=1000, 0<m<100000, s != t)
輸出描述:
輸出 一行有兩個數, 最短距離及其花費。示例1
輸入
3 2 1 2 5 6 2 3 4 5 1 3
輸出
9 11
程式碼如下:(一定要注意)
#include<stdio.h> #include<string.h> #include<stdlib.h> #define N 1005 #define MAX 0x3f3f3f3f int map[N][N],f[N][N],dis[N],path[N],fee[N],vis[N]; void dijkstra(int s,int t,int n){ int i,j,v; v=s; dis[s]=fee[s]=0; vis[s]=1; path[s]=s; for(i=1;i<=n;i++) if(!vis[i]&&map[s][i]!=MAX){ dis[i]=map[s][i]; fee[i]=f[s][i]; path[i]=s; } for(i=0;i<n-1;i++){ int min=MAX; for(j=1;j<=n;j++) if(!vis[j]&&dis[j]<min){ min=dis[j]; v=j; } if(min==MAX) break; vis[v]=1; for(j=1;j<=n;j++) if(!vis[j]&&map[v][j]!=MAX){ if(dis[j]>dis[v]+map[v][j]){ dis[j]=dis[v]+map[v][j]; fee[j]=fee[v]+f[v][j]; path[j]=v; }else if(dis[j]==dis[v]+map[v][j]&&fee[j]>fee[v]+f[v][j]){ fee[j]=fee[v]+f[v][j]; path[j]=v; } } } printf("%d %d\n",dis[t],fee[t]); } int main(){ int n,m,a,b,d,p,s,t,i,j; while(scanf("%d %d",&n,&m)!=EOF){ if(n==0&&m==0) break; for(i=1;i<=n;i++){ for(j=1;j<=n;j++) map[i][j]=f[i][j]=MAX; dis[i]=fee[i]=MAX; vis[i]=0; path[i]=-1; } while(m--){ scanf("%d %d %d %d",&a,&b,&d,&p); if(map[a][b]>d){ map[a][b]=map[b][a]=d; f[a][b]=f[b][a]=p; }else if(map[a][b]==d&&f[a][b]>p) f[a][b]=f[b][a]=p; } scanf("%d %d",&s,&t); dijkstra(s,t,n); } return 0; }
額外測試資料:
//測試資料
2 2
1 2 5 10
2 1 4 12
1 2
4 12
4 4
1 2 5 6
2 3 4 5
1 4 5 10
4 3 4 2
1 3
9 11
6 7
1 2 5 6
1 3 5 1
2 6 2 1
3 4 1 1
4 2 1 1
4 5 1 1
5 2 3 1
5 6
4 3