Time Limit: 1000 ms Memory Limit: 65536 KiB
Problem Description
做爲一個資深驢友,小新有一張珍藏的自駕遊線路圖,圖上詳細的標註了全國各個城市之間的高速公路距離和公路收費情況,現在請你編寫一個程序,找出一條出發地到目的地之間的最短路徑,如果有多條路徑最短,則輸出過路費最少的一條路徑。
Input
連續T組數據輸入,每組輸入數據的第一行給出四個正整數N,M,s,d,其中N(2 <= N <= 500)是城市數目,城市編號從0~N-1,M是城市間高速公路的條數,s是出發地的城市編號,d是目的地的城市編號;隨後M行,每行給出一條高速公路的信息,表示城市1、城市2、高速公路長度、收費額,中間以空格間隔,數字均爲整數且不超過500,輸入數據均保證有解。
Output
在同一行中輸出路徑長度和收費總額,數據間用空格間隔。
Sample Input
1
4 5 0 3
0 1 1 20
1 3 2 30
0 3 4 10
0 2 2 20
2 3 1 20
Sample Output
3 40
#include <stdio.h>
#include <string.h>
#define MAX 0x3f3f3f
int dis[505][505], mon[505][505], mo[505], di[505];
int vis[505];
void dijkstra(int n, int s, int d)
{
vis[s] = 1;
int i, q, min, k;
for(i=0;i<n;i++)
{
mo[i] = mon[0][i];
di[i] = dis[0][i];
}
for(q=1; q<n; q++)
{
min = MAX;
for(i=0;i<n;i++)
{
if(vis[i]==0&&di[i]<min)
{
k = i;
min = di[i];
}
}
vis[k] = 1;
for(i=0;i<n;i++)
{
if(vis[i]==0&&dis[k][i]<MAX)
{
if(di[i] > dis[k][i]+min||(di[i]==dis[k][i]+min&&mo[i]>mon[k][i]+mo[k]))
{
di[i] = dis[k][i] + di[k];
mo[i] = mon[k][i] + mo[i];
}
}
}
}
printf("%d %d\n", di[d], mo[d]);
}
int main()
{
int t, n, m, s, d, i, c1, c2, ll, cos;
scanf("%d", &t);
while(t--)
{
scanf("%d %d %d %d", &n, &m, &s, &d);
//初始化
memset(dis, MAX, sizeof(dis));
memset(vis, 0, sizeof(vis));
memset(mon, 0, sizeof(mon));
for(i=0;i<n;i++)
{
dis[i][i] = 0;
mon[i][i] = 0;
}
while(m--)
{
scanf("%d %d %d %d", &c1, &c2, &ll, &cos);
if(ll<dis[c1][c2]||(ll==dis[c1][c2]&&cos<mon[c1][c2]))
{
dis[c1][c2] = dis[c2][c1] = ll;
mon[c1][c2] = mon[c2][c1] = cos;
}
}
dijkstra(n, s, d);
}
return 0;
}