Description
题目大意:给定一个图,要求你找到最短路和最快的路
Input
n代表n个点,m代表m条边
接下来m行,每行分别输入V1,V2,oneway,length,time
如果oneway=1代表V1,V2是单向的,否则则是双向的,length代表V1到V2的长度,time代表V1到V2的时间
最后一行 source和destination代表起点和终点
Output
如果最短路有多条,求其中最快的;如果最快路有多条,求经过节点最少的;如果最快路和最短路相同,则一起输出,反之则分别输出出来
解题思路
算法标签:最短路Dijstra
1.对路程求最短路,如果最短路相同,则比较时间
2.对时间求最短路,如果最快时间相同,则比较节点数
其实这题就是麻烦,就是求最短路,附加一些条件而已(蒟蒻)
代码
//TSWorld
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
using namespace std;
const int N = 505;
const int MAXX = 0x3f3f3f3f;
// 记录距离和时间
int Map[N][N];
int Times[N][N];
// 邻接表
vector<int>edge[N];
// 记录src到每个点的距离和时间,以及点的个数
int dis[N];
int tim[N];
int node[N];
// 记录前驱
int dispre[N];
int timpre[N];
// 记录路径
vector<int>dispath;
vector<int>timpath;
void Dijstra_path(int src,int n)
{
// 寻找最小边及下标
int minn = 0,p = 0;
// 记录该点是否被访问
bool vis[n+5];
memset(vis,false,sizeof(vis));
// dis[i] i到src的距离
// tim[i] i到src的时间
for(int i = 0;i < n+3;i++)
dis[i] = MAXX;
for(int i = 0;i < n+3;i++)
tim[i] = MAXX;
for(int i = 0;i < n;i++)
{
dis[i] = Map[src][i];
tim[i] = Times[src][i];
}
for(int i = 0;i < n;i++)
dispre[i] = i;
// 初始化src到src距离为0,时间为0
dis[src] = 0;
vis[src] = true;
tim[src] = 0;
// Dijstra求最短路
for(int i = 0;i < n;i++)
{
minn = MAXX;
p = -1;
for(int j = 0;j < n;j++)
{
if((!vis[j])&&(minn > dis[j])){
minn = dis[j];
p = j;
}
}
if(p == -1)
break;
vis[p] = true;
for(int j = 0;j < edge[p].size();j++)
{
if(!vis[edge[p][j]])
{
if(dis[edge[p][j]] > dis[p] + Map[p][edge[p][j]])
{
dis[edge[p][j]] = dis[p] + Map[p][edge[p][j]];
tim[edge[p][j]] = tim[p] + Times[p][edge[p][j]];
dispre[edge[p][j]] = p;
}
else if(dis[edge[p][j]] == dis[p] + Map[p][edge[p][j]])
{
if(tim[edge[p][j]] > tim[p] + Times[p][edge[p][j]]){
tim[edge[p][j]] = tim[p] + Times[p][edge[p][j]];
dispre[edge[p][j]] = p;
}
}
}
}
}
}
void Dijstra_time(int src,int n)
{
// 寻找最小边及下标
int minn = 0,p = 0;
// 记录该点是否被访问
bool vis[n+5];
memset(vis,false,sizeof(vis));
// 初始化Tim
for(int i = 0;i < n+3;i++)
tim[i] = MAXX;
for(int i = 0;i < n;i++){
tim[i] = Times[src][i];
timpre[i] = i;
}
tim[src] = 0;
vis[src] = true;
// Dijstra
for(int i = 0;i < n;i++)
{
minn = MAXX,p = -1;
for(int j = 0;j < n;j++)
{
if((!vis[j])&&(minn > tim[j])){
minn = tim[j];
p = j;
}
}
if(p == -1)
break;
vis[p] = true;
for(int j = 0;j < edge[p].size();j++)
{
if(!vis[edge[p][j]])
{
if(tim[edge[p][j]] > tim[p] + Times[p][edge[p][j]])
{
tim[edge[p][j]] = tim[p] + Times[p][edge[p][j]];
node[edge[p][j]] = node[p] + 1;
timpre[edge[p][j]] = p;
}
else if((tim[edge[p][j]] == tim[p] + Times[p][edge[p][j]])&&(node[p]+1 < node[edge[p][j]]))
{
node[edge[p][j]] = node[p] +1;
timpre[edge[p][j]] = p;
}
}
}
}
}
void Print_path(int dest)
{
if(dispre[dest] == dest){
dispath.push_back(dest);
return;
}
Print_path(dispre[dest]);
dispath.push_back(dest);
}
void Print_tim(int dest)
{
if(timpre[dest] == dest){
timpath.push_back(dest);
return;
}
Print_tim(timpre[dest]);
timpath.push_back(dest);
}
int main()
{
int n = 0,m = 0;
int one_way = 0,length = 0,time = 0;
int source = 0,destination = 0;
int V1 = 0,V2 = 0;
cin>>n>>m;
for(int i = 0;i < n+1;i++)
for(int j = 0;j < n+1;j++){
Map[i][j] = MAXX;
Times[i][j] = MAXX;
}
for(int i = 1;i <= m;i++)
{
cin>>V1>>V2>>one_way>>length>>time;
if(one_way == 1){
Map[V1][V2] = length;
Times[V1][V2] = time;
edge[V1].push_back(V2);
}
else
{
Map[V1][V2] = length;
Times[V1][V2] = time;
edge[V1].push_back(V2);
Map[V2][V1] = Map[V1][V2];
Times[V2][V1] = Times[V1][V2];
edge[V2].push_back(V1);
}
}
cin>>source>>destination;
Dijstra_path(source,n);
cout<<"Distance = "<<dis[destination];
dispath.push_back(source);
Print_path(destination);
Dijstra_time(source,n);
timpath.push_back(source);
Print_tim(destination);
if(timpath == dispath)
{
cout<<"; Time = "<<tim[destination]<<": ";
for(int i = 0;i < dispath.size();i++)
if(i == 0)
cout<<dispath[i];
else
cout<<" -> "<<dispath[i];
}
else
{
cout<<": ";
for(int i = 0;i < dispath.size();i++)
if(i==0)
cout<<dispath[i];
else
cout<<" -> "<<dispath[i];
cout<<endl;
cout<<"Time = "<<tim[destination]<<": ";
for(int i = 0;i < timpath.size();i++)
if(i==0)
cout<<timpath[i];
else
cout<<" -> "<<timpath[i];
}
return 0;
}