2次Dijkstra
一定要好好看题鸭哭哭,看到在最短距离相同时选择最快的路,就想当然的认为在最短时间相同时选择最短的路,会导致测试点2错误。
#include <iostream>
#include <vector>
#include <climits>
#include <algorithm>
using namespace std;
int L[510][510];
int T[510][510];
int preL[510];
int preT[510];
int len[510];
int tim[510];
int thoughCitiesForMinT[510];
int timForMinL[510];
bool vis[510];
void DijkstraL(int s,int n){
fill(preL,preL + 510,-1);
fill(len,len + 510,INT_MAX);
fill(timForMinL,timForMinL + 510,INT_MAX);
fill(vis,vis + 510,false);
len[s] = 0;
timForMinL[s] = 0;
for(int i = 0;i < n;i++){
int u = -1,MINL = INT_MAX,MINT = INT_MAX;
for(int j = 0;j < n;j++){
if(vis[j] == false && (len[j] < MINL || (len[j] == MINL && timForMinL[j] < MINT))){
u = j;
MINL = len[j];
MINT = timForMinL[j];
}
}
if(u == -1) return;
vis[u] = true;
for(int v = 0;v < n;v++){
if(vis[v] == false && L[u][v] != INT_MAX && (len[u] + L[u][v] < len[v] || (len[u] + L[u][v] == len[v] && timForMinL[u] + T[u][v] < timForMinL[v]))){
len[v] = len[u] + L[u][v];
timForMinL[v] = timForMinL[u] + T[u][v];
preL[v] = u;
}
}
}
}
void DijkstraT(int s,int n){
fill(preT,preT + 510,-1);
fill(tim,tim + 510,INT_MAX);
fill(thoughCitiesForMinT,thoughCitiesForMinT + 510,INT_MAX);
fill(vis,vis + 510,false);
tim[s] = 0;
thoughCitiesForMinT[s] = 0;
for(int i = 0;i < n;i++){
int u = -1,MINT = INT_MAX,MINL = INT_MAX;
for(int j = 0;j < n;j++){
if(vis[j] == false && (tim[j] < MINT || (tim[j] == MINT && thoughCitiesForMinT[j] < MINL))){
u = j;
MINT = tim[j];
MINL = thoughCitiesForMinT[j];
}
}
if(u == -1) return;
vis[u] = true;
for(int v = 0;v < n;v++){
if(vis[v] == false && T[u][v] != INT_MAX && (tim[u] + T[u][v] < tim[v] || (tim[u] + T[u][v] == tim[v] && thoughCitiesForMinT[u] + 1 < thoughCitiesForMinT[v]))){
tim[v] = tim[u] + T[u][v];
thoughCitiesForMinT[v] = thoughCitiesForMinT[u] + 1;
preT[v] = u;
}
}
}
}
int main(){
int n,m;
scanf("%d %d",&n,&m);
// n : 城市个数
// m : 道路条数
for(int i = 0;i < 510;i++){
for(int j = 0;j < 510;j++){
L[i][j] = INT_MAX;
T[i][j] = INT_MAX;
}
}
for(int i = 0;i < m;i++){
int v1,v2,oneWay,l,t;
scanf("%d %d %d %d %d",&v1,&v2,&oneWay,&l,&t);
if(oneWay == 1){ // 是v1->v2单行道
L[v1][v2] = l;
T[v1][v2] = t;
}else{ // 是双行
L[v1][v2] = l;
L[v2][v1] = l;
T[v1][v2] = t;
T[v2][v1] = t;
}
}
int source,destination;
scanf("%d %d",&source,&destination);
DijkstraL(source,n);
DijkstraT(source,n);
int d = destination;
vector<int> minLength;
while(preL[d] != -1){
if(minLength.size() != 0){
minLength.insert(minLength.begin(),d);
}else{
minLength.push_back(d);
}
d = preL[d];
}
if(minLength.size() != 0){
minLength.insert(minLength.begin(),d);
}else{
minLength.push_back(d);
}
d = destination;
vector<int> minTime;
while(preT[d] != -1){
if(minTime.size() != 0){
minTime.insert(minTime.begin(),d);
}else{
minTime.push_back(d);
}
d = preT[d];
}
if(minTime.size() != 0){
minTime.insert(minTime.begin(),d);
}else{
minTime.push_back(d);
}
int lenL = minLength.size(),lenT = minTime.size();
bool sameRoad = true;
if(lenL != lenT)
sameRoad = false;
else{
for(int i = 0;i < lenL;i++){
if(minLength[i] != minTime[i]){
sameRoad = false;
break;
}
}
}
if(sameRoad == true){
printf("Distance = %d; Time = %d:",len[destination],tim[destination]);
for(int i = 0;i < lenL;i++){
printf(" %d",minLength[i]);
if(i != lenL - 1)
printf(" ->");
}
}else{
printf("Distance = %d:",len[destination]);
for(int i = 0;i < lenL;i++){
printf(" %d",minLength[i]);
if(i != lenL - 1)
printf(" ->");
}
printf("\nTime = %d:",tim[destination]);
for(int i = 0;i < lenT;i++){
printf(" %d",minTime[i]);
if(i != lenT - 1)
printf(" ->");
}
}
system("pause");
return 0;
}