数据结构实验之图论七:驴友计划
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
Hint
Source
xam
#include<stdio.h>
#include<string.h>
const int inf=0x3f3f3f;
const int maxn =1010;
int mp[maxn][maxn];//存最短路
int v[maxn][maxn];//存最少要花的钱
int n, m, s, d;
void Folyd()//弗洛里的算法
{
int i,j,k;
for( k = 0; k < n; k++)
{
for(i = 0; i < n; i++)
{
for(j = 0; j < n; j++)
{
if(i != j)
{
if(mp[i][j] > mp[i][k] + mp[k][j])//从i到j的路径距离大于i到k,再从k到j的距离则更新,要短的路径
{
//也就是,如果有个中介给我从i到k,k再到j,比我直接从i到j要少,这是folyd算法的精华
mp[i][j] = mp[i][k] + mp[k][j];
v[i][j] = v[i][k] + v[k][j];
}
if(mp[i][j] == mp[i][k] + mp[k][j])//若相等则考虑最少花费
{
if(v[i][j] > v[i][k] + v[k][j])//从i到j的花费大于i到k,再从k到j的距离则更新,要最少的花费
v[i][j] = v[i][k] + v[k][j];
}
}
}
}
}
}
int main()
{
int T,j,i;
scanf("%d",&T);
while(T--)
{
scanf("%d%d%d%d",&n,&m,&s,&d);
for(i=0; i<n; i++)
{
for( j=0; j<n; j++)
{
if(j==i)
mp[i][j]=v[i][j]=0;//初始化,在flory里好更新
else mp[i][j]=v[i][j]=inf;
}
}
for(i = 0; i < m; i++)
{
int a,b,c,d;
scanf("%d%d%d%d",&a,&b,&c,&d);
mp[a][b]=mp[b][a]=c;
v[a][b]=v[b][a]=d;//无向图
}
Folyd();
printf("%d %d\n",mp[s][d],v[s][d]);
}
return 0;
}