思路就是分别把最快路径和最短路径找出来 然后比较这两个路径是否一样 输出即可
单源最短路径 用的dijkstra算法
dijkstra算法大概讲解如下:
例如以v0为出发点: v0 v1 v2 v3 v4 v5 当前出发点
(0,λ) (∞,λ) (∞,λ) (∞,λ) (∞,λ) (∞,λ) v0
(50,v0) (10,v0) (∞,λ) (45,v0) (∞,λ) v2 选最短的路径作为出发点
(50,v0) (25,v2) (45,v0) (∞,λ) v3
(45,v3) (45,v0) (∞,λ) v1
(45,v0) (∞,λ) v4
(∞,λ) v5
然后可以得到v0到其他点的路径和路径长度
v0->v2->v3->v1 45
v0->v2 10
v0->v2->v3 25
v0->v4 45
v0->v5 无最短路径
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<set>
using namespace std;
int ti[501][501]; //ti[i][j]表示i到j的时间
int way[501][501]; //way[i][j]表示i到j的距离
bool vis1[501],vis2[501];
int useTime1[501]; //useTime[i] 表示起点到i点的时间
int useLen1[501]; //useLen[i] 表示起点到i点的距离
int useLen2[501]; //useLen[i] 表示起点到i点的距离
int useNode2[501]; // useNode[i] 表示起点到i点所走过的结点数
int path1[501],path2[501];
int way1[501],way2[501];
int root1,root2;
int s,e;
int n,m,v1,v2,flag,len,t;
void dij1(int start,int end){
int minStart = start;
for(int t=0;t<n-1;t++){
vis1[minStart] = true;
for(int i=0;i<n;i++){
if(!vis1[i] && ti[minStart][i]>0){ //两点有边并且i点还没当过minStart
if(useTime1[minStart]+ti[minStart][i]<useTime1[i]){ //花的时间少就替换
useTime1[i] = useTime1[minStart]+ti[minStart][i];
useLen1[i] = useLen1[minStart] + way[minStart][i];
path1[i] = minStart;
} else if(useTime1[minStart]+ti[minStart][i]==useTime1[i]){ //花的时间一样,选路径短就替换
if(useLen1[minStart]+way[minStart][i]<useLen1[i]){
useLen1[i] = useLen1[minStart] + way[minStart][i];
path1[i] = minStart;
}
}
}
}
int min=999999;
for(int j=0;j<n;j++){
if(!vis1[j] && useTime1[j]<min){
minStart = j;
min = useTime1[j];
}
}
}
int i = end;
while(i!=-1){
way1[root1++]=i;
i = path1[i] ;
}
}
void dij2(int start,int end){
int minStart = start;
for(int t=0;t<n-1;t++){
vis2[minStart] = true;
for(int i=0;i<n;i++){
if(!vis2[i] && way[minStart][i]>0){ //两点有边并且i点还没当过minStart
if(useLen2[minStart]+way[minStart][i]<useLen2[i]){ //走的路径少就替换
useLen2[i] = useLen2[minStart]+way[minStart][i];
useNode2[i] = useNode2[minStart]+1;
path2[i] = minStart;
} else if(useLen2[minStart]+way[minStart][i]==useLen2[i]){ //走的路径一样,走的节点少就替换
if(useNode2[minStart]+1<useNode2[i]){
useNode2[i] = useNode2[minStart]+1;
path2[i] = minStart;
}
}
}
}
int min=999999;
for(int j=0;j<n;j++){
if(!vis2[j] && useLen2[j]<min){
minStart = j;
min = useLen2[j];
}
}
}
int i = end;
while(i!=-1){
way2[root2++]=i;
i = path2[i] ;
}
}
bool isSame(){
if(root1!=root2)
return false;
for(int i=0;i<root1;i++)
if(way1[i]!=way2[i])
return false;
return true;
}
void print(){
if(isSame()){
cout<<"Time = "<<useTime1[e]<<"; Distance = "<<useLen2[e]<<": ";
cout<<s;
for(int i=root1-2;i>=0;i--)
cout<<" => "<<way1[i];
cout<<endl;
} else{
cout<<"Time = "<<useTime1[e]<<": ";
cout<<s;
for(int i=root1-2;i>=0;i--)
cout<<" => "<<way1[i];
cout<<endl;
cout<<"Distance = "<<useLen2[e]<<": ";
cout<<s;
for(int i=root2-2;i>=0;i--)
cout<<" => "<<way2[i];
cout<<endl;
}
}
int main()
{
cin>>n>>m;
for(int i=1;i<=m;i++){
cin>>v1>>v2>>flag>>len>>t;
way[v1][v2] = len;
ti[v1][v2] = t;
if(flag==0){
way[v2][v1] = len;
ti[v2][v1] = t;
}
}
for(int i=0;i<n;i++){
path1[i] = -1;
path2[i] = -1;
useTime1[i] = 99999;
useLen1[i] = 99999;
useLen2[i] = 99999;
useNode2[i] = 1;
}
root1=0;
root2=0;
memset(vis1,false,sizeof(vis1));
memset(vis2,false,sizeof(vis2));
cin>>s>>e;
useTime1[s]=0;
useLen1[s]=0;
useLen2[s]=0;
dij1(s,e);
dij2(s,e);
print();
return 0;
}
第一次写文章
有质疑或者疑惑的地方可以评论哈