A traveler's map gives the distances between cities along the highways, together with the cost of each highway. Now you are supposed to write a program to help a traveler to decide the shortest path between his/her starting city and the destination. If such a shortest path is not unique, you are supposed to output the one with the minimum cost, which is guaranteed to be unique.
Input Specification:
Each input file contains one test case. Each case starts with a line containing 4 positive integers N, M, S, and D, where N (≤500) is the number of cities (and hence the cities are numbered from 0 to N−1); M is the number of highways; S and D are the starting and the destination cities, respectively. Then M lines follow, each provides the information of a highway, in the format:
City1 City2 Distance Cost
where the numbers are all integers no more than 500, and are separated by a space.
Output Specification:
For each test case, print in one line the cities along the shortest path from the starting point to the destination, followed by the total distance and the total cost of the path. The numbers must be separated by a space and there must be no extra space at the end of output.
Sample Input:
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:
0 2 3 3 40
思路:
此题属于dijkstra双边权问题,直接使用dijkstra算法找到满足题意条件的边长
1. 对于边权问题的处理方法: 设定w[ k ] = weight[ u ][k] + w[u]; //求出满足题意要求的边权值
2. 对于点权问题的处理方法: w[ k ] = weight[k]+ w[ u ] //求出满足题意要求点权值
3. 对于求满足题意最短路径(有多条)求总共的条数的问题: (有更小的边)num_path[ start]= 1 num_path[ k ] = numpath[ u ]
当出现相同的边 num[k] = numpath[ k ] +numpath[ u ];
4. 对于求满足题意路径中结点个数问题: node_path[ k ] = node[ u ] + 1
3. 对于满足题意要求路径输出问题:1. 设定数组dispre保存所有满足要求(不仅仅是长度)路径的父节点,通过disdfs()输出路径
2.第二种方法:使用dfs算法遍历,设定vector<>path[ maxsize ](二维向量)存储最短路径 长度(注意只满足长度这个条件),在dfs中就处理题中其他的条件,输出满足题意要求的最短路径。
本题代码:
#include<iostream>
#include<vector>
using namespace std;
const int maxsize = 520;
const int inf = 0x3f3f3f;
int dis[maxsize],edge[maxsize][maxsize],weight[maxsize][maxsize],w[maxsize],dispre[maxsize];//存储路径数组
vector<int> dispath;
int n,m,start,endll;
bool visit[maxsize];
void dfs(int end){
if(end == dispre[end]){
dispath.push_back(end);
return;
}
dfs(dispre[end]);
dispath.push_back(end);
}
void dijkstra(int start){
dis[start]=0;
for(int i=0;i<n;i++){
int min=inf,u=-1;
for(int j=0;j<n;j++){
if(dis[j]<min && visit[j]==false){
min=dis[j];
u=j;
}
}
visit[u]=true;
if(u==-1 || u==endll) return;
for(int k=0;k<n;k++){
if(visit[k]==false && edge[u][k]!=inf){
if(dis[u]+edge[u][k]<dis[k]){
dis[k]=dis[u]+edge[u][k];
dispre[k]=u;
w[k]=w[u]+weight[u][k];
}else if(dis[u]+edge[u][k]==dis[k] && w[k]>w[u]+weight[u][k]){
dispre[k]=u;
w[k]=w[u]+weight[u][k];
}
}
}
}
}
int main(){
fill(edge[0],edge[0]+maxsize*maxsize,inf);
fill(weight[0],weight[0]+maxsize*maxsize,inf);
fill(dis,dis+maxsize,inf);
scanf("%d%d%d%d",&n,&m,&start,&endll);
int from,to,length,cost;
for(int i=0;i<m;i++){
scanf("%d%d%d%d",&from,&to,&length,&cost);
edge[from][to]=edge[to][from]=min(edge[from][to],length);
weight[from][to]=weight[to][from]= min(weight[from][to],cost);
}
for(int i=0;i<n;i++){
dispre[i]=i;
}
dijkstra(start);
// for(auto i=0;i<n;i++){ 检验dijkstra
// cout<<dis[i]<<endl;
// }
dfs(endll);
for(auto i=0;i<dispath.size();i++){
if(i!=0)
printf(" ");
printf("%d",dispath[i]);
}
printf(" %d %d\n",dis[endll],w[endll]);
return 0;
}