有了一张自驾旅游路线图,你会知道城市间的高速公路长度、以及该公路要收取的过路费。现在需要你写一个程序,帮助前来咨询的游客找一条出发地和目的地之间的最短路径。如果有若干条路径都是最短的,那么需要输出最便宜的一条路径。
输入格式:
输入说明:输入数据的第1行给出4个正整数N、M、S、D,其中N(2≤N≤500)是城市的个数,顺便假设城市的编号为0~(N−1);M是高速公路的条数;S是出发地的城市编号;D是目的地的城市编号。随后的M行中,每行给出一条高速公路的信息,分别是:城市1、城市2、高速公路长度、收费额,中间用空格分开,数字均为整数且不超过500。输入保证解的存在。
输出格式:
在一行里输出路径的长度和收费总额,数字间以空格分隔,输出结尾不能有多余空格。
输入样例:
4 5 0 3
0 1 1 20
1 3 2 30
0 3 4 10
0 2 2 20
2 3 1 20
输出样例:
3 40
思路:
dijkstra算法。
这里多了一个cost的问题。
调试了半天,终于做出来了。
- 在第一条红线的那一步,一定不能将处理dist和cost数组,
- 这一步仅仅只招未收录的顶点,第二条划红线的步骤才是核心的更新距离的公式。
另外,对于
- for(V的每个零界点W)这一步一定不不能判断已经读过。
这一步很大程度上就是算法精华,但是本题的测试用例明显没有测出这一点。
为了更新已有的邻接点的值,必须不能判断visit。
#include <iostream>
#include <queue>
#include <algorithm>
#include <string.h>
using namespace std;
int MatrixDist[501][501]={0};
int MatrixCost[501][501]={0};
int dist[501]={0};
int costm[501]={0};
int visit[501]={0};
//int pay[501]={0};
int N,M,S,D;
void Dijstra(int s)
{
visit[s]=1;
int minvertex=s;
while(1)
{
int mindist=1000;
int tmp=-1;
for (int i=0;i<N;i++)
{
if(visit[i]==0&&MatrixDist[i][minvertex]<mindist){
//寻找最近节点的时候不能够改动dist或者其他cost数组的值。
//if(dist[i]>=MatrixDist[i][minvertex]+dist[minvertex]){
//dist[i]=MatrixDist[i][minvertex]+dist[minvertex];
//costm[i]=MatrixCost[i][minvertex]+costm[minvertex];
if(tmp!=-1){//不是第一次更新了
if(MatrixDist[i][minvertex]==MatrixDist[tmp][minvertex])
if(MatrixCost[i][minvertex]<MatrixCost[tmp][minvertex]){
tmp=i;//价格少的路
}
}
else
tmp=i;
//costm[tmp]=MatrixCost[tmp][minvertex]+costm[minvertex];
mindist=dist[tmp];//最小值
}
}
minvertex=tmp;//保存下来的最小节点
if(mindist==1000)
break;
visit[minvertex]=1;/*************这里开始做*****************/
for(int i=0;i<N;i++)
{
if(MatrixDist[i][minvertex]<1000)
if(MatrixDist[i][minvertex]+dist[minvertex]<=dist[i]){
if (MatrixDist[i][minvertex]+dist[minvertex]==dist[i]){
if (costm[i]>MatrixCost[i][minvertex]+costm[minvertex])
costm[i]=MatrixCost[i][minvertex]+costm[minvertex];
}
else{
dist[i]=MatrixDist[i][minvertex]+dist[minvertex];
costm[i]=MatrixCost[i][minvertex]+costm[minvertex];
}
}
}
}
}
int main()
{
cin>>N>>M>>S>>D;
for (int i=0;i<N;i++)
for(int j=0;j<N;j++){
MatrixCost[i][j]=1000;
MatrixDist[i][j]=1000;
}
for(int i=0;i<N;i++){
MatrixCost[i][i]=0;
MatrixDist[i][i]=0;
}
for(int i=0;i<M;i++){
int c1,c2,len,cost;
cin>>c1>>c2>>len>>cost;
MatrixCost[c1][c2]=MatrixCost[c2][c1]=cost;
MatrixDist[c1][c2]=MatrixDist[c2][c1]=len;
}
for (int i=0;i<N;i++){
dist[i]=1000;
costm[i]=1000;
if(MatrixDist[i][S]<dist[i]){
dist[i]=MatrixDist[i][S];
costm[i]=MatrixCost[i][S];
}
}
memset(visit,0,sizeof(visit));
Dijstra(S);
cout<<dist[D]<<" "<<costm[D]<<endl;
return 0;
}