九度題目1008:最短路徑問題
題目1008:最短路徑問題時間限製:1 秒內存限製:32 兆特殊判題:否提交:5129解決:1634
題目描述:
給你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時輸入結束。
(1n=1000, 0m100000, s != t)
輸出:
輸出 一行有兩個數, 最短距離及其花費。
樣例輸入:
3 2
1 2 5 6
2 3 4 5
1 3
0 0
樣例輸出:
9 11
來源:
2010年浙江大學計算機及軟件工程研究生機試真題
AC代碼:
用的迪傑斯特拉最短路徑算法
#include<stdio.h>
#include<string.h>
#define INF 0x11111111
int map[1010][1010],w[1010][1010];
int way[1010],value[1010],flag[1010];
int main()
{
int i,j,n,m,x,y,z,v,s,t;
while(scanf("%d %d",&n,&m),n!=0&&m!=0)
{
memset(map,INF,sizeof(map));//數組初始化為最大值
memset(w,INF,sizeof(w));
for(i=0;i<m;i++)
{
scanf("%d %d %d %d",&x,&y,&z,&v);
map[x][y]=z;//儲存正反向的路徑長度和花費
map[y][x]=z;
w[x][y]=v;
w[y][x]=v;
}
scanf("%d %d",&s,&t);
memset(way,INF,sizeof(way));//此數組儲存從s到i的長度
memset(value,INF,sizeof(value));//此數組儲存從s到i的花費
memset(flag,0,sizeof(flag));//標記路徑點是否被加入最短路徑中
flag[s]=1;//起點已經被標記為加入最短路徑
for(i=1;i<=n;i++)//開始賦值
{
way[i]=map[s][i];
value[i]=w[s][i];
}
for(i=1;i<n;i++)
{
int min=INF;
int k=0;
for(j=1;j<=n;j++)//找出一個距離起點最近的路徑
{
if(flag[j]==0&&(way[j]<min||(way[j]==min&&value[k]<value[j]))) //如果長度相等,取花費較小的那一個
{
min=way[j];
k=j;
}
}
flag[k]=1;
for(j=1;j<=n;j++)//找出距離剛剛選出來的點最近的距離組成新的路徑
{
if(flag[j]==0&&(way[k]+map[k][j]<way[j]||(way[j]==way[k]+map[k][j]&&value[k]+w[k][j]<value[j])))
{
way[j]=way[k]+map[k][j];
value[j]=value[k]+w[k][j];
}
}
}
printf("%d %d\n",way[t],value[t]);
}
return 0;
}
最後更新:2017-04-03 08:26:11