数据结构实验之图论七:驴友计划
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
Output
3 40
Hint
//Floyd算法
#include <bits/stdc++.h>
#include <queue>
using namespace std;
const int INF = 0x3f3f3f3f;
int e[510][510];//e是路径长度
int t,n,m,s,d,i,j,k,x,y,w,z;
int dis[510][510];//dis是收费总额
void Floyd(int s,int d)
{
for(k=0;k<n;k++)//n个城市,也是中途历经的点
{
for(i=0;i<n;i++)//去的点
{
for(j=0;j<n;j++)//到的点
{
if(e[i][j]>e[i][k]+e[k][j]||e[i][j]==e[i][k]+e[k][j])
{//如果从这i直接到j的路径长度相等或者大于中途经过其他点
if(e[i][j]>e[i][k]+e[k][j])//如果路径长度大于则直接更新
{
e[i][j]=e[i][k]+e[k][j];
dis[i][j]=dis[i][k]+dis[k][j];
}
else//当二者相等时,再比较收费额的大小
{//这时二者的路径长度相等,不用再更新了
if(dis[i][j]>dis[i][k]+dis[k][j])
dis[i][j]=dis[i][k]+dis[k][j];
}
}
}
}
}
cout<<e[s][d]<<" "<<dis[s][d]<<endl;
}
int main()
{
int t;
cin>>t;
while(t--)
{
cin>>n>>m>>s>>d;
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
if(i==j)//从这个城市到同一个城市的路径和收费额均为0
{
e[i][j]=0;
dis[i][j]=0;
}
else//否则,暂记为无穷大
{
e[i][j]=INF;
dis[i][j]=INF;
}
}
}
for(i=1;i<=m;i++)
{
cin>>x>>y>>w>>z;
e[x][y]=w;
e[y][x]=w;
dis[x][y]=z;
dis[y][x]=z;//该图为无向图,来去时的路径长度和收费额都一样
}
Floyd(s,d);
}
return 0;
}