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
比普通的迪杰斯特拉算法“进阶”的地方是有两个变量,可以用结构体来存储。
判断的条件相对改变一下就ok了。很简单。。这个题目数据超级水。。。。
AC代码:
#include <iostream>
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
const int N = 550;
struct node
{
int path;
int cost;
} mp[N][N];
int vis[N];
int dis1[N];
int dis2[N];
int n,m;
void Dij(int v0)
{
for(int i=0;i<n;i++)
{
dis1[i] = mp[v0][i].path;
dis2[i] = mp[v0][i].cost;
vis[i] = 0;
}
vis[v0] = 1;
dis1[v0] = 0;
dis2[v0] = 0;
int pos;
int mm1;
int mm2;
for(int i=1;i<n;i++)
{
mm1 = INF;
mm2 = INF;
for(int j=0;j<n;j++)
{
if(vis[j]==0&&(dis1[j]<mm1||dis2[j]<mm2))///或者后面应该是 前面的相等+后面的小于
{
pos = j;
mm1 = dis1[j];
mm2 = dis2[j];
}
}
if(mm1==INF&&mm2==INF)
break;
vis[pos] = 1;
for(int j=0;j<n;j++)
{
if(dis1[j]>dis1[pos]+mp[pos][j].path||dis2[j]>dis2[pos]+mp[pos][j].cost)///或者后面应该是 前面的相等+后面的大于
{
dis1[j] = dis1[pos] + mp[pos][j].path;
dis2[j] = dis2[pos] + mp[pos][j].cost;
}
}
}
}
int main()
{
int T;
int s,e;
scanf("%d",&T);
while(T--)
{
scanf("%d %d %d %d",&n,&m,&s,&e);
for(int i=0; i<n; i++)
{
for(int j=0; j<=i; j++)
{
if(j==i)
{
mp[i][j].path = mp[j][i].path = 0;
mp[i][j].cost = mp[j][i].cost = 0;
}
else
{
mp[i][j].path = mp[j][i].path = INF;
mp[i][j].cost = mp[j][i].cost = INF;
}
}
}
int a,b,c,d;
for(int i=0;i<m;i++)
{
scanf("%d%d%d%d",&a,&b,&c,&d);
if(mp[a][b].path>c)
mp[a][b].path = mp[b][a].path = c;
if(mp[a][b].cost>d)
mp[a][b].cost = mp[b][a].cost = d;
}
Dij(s);
printf("%d %d\n",dis1[e],dis2[e]);
}
return 0;
}