1. 题目
给⼀张地图,两个结点中既有距离也有时间,有的单⾏有的双向,要求根据地图推荐两条
路线:⼀条是最快到达路线,⼀条是最短距离的路线。
2. 代码
- one-way 单行道
- 分两次写DFS
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;
const int MAXV = 510;
const int INF = 0x3fffffff;
int n, m, st, ed;
int G[MAXV][MAXV], T[MAXV][MAXV]; //两个第一标尺
int d[MAXV], Time[MAXV]; //两个第一标尺的最短距离
bool vis[MAXV] = {false};
vector<int> dis_path, time_path;
int dis_pre[MAXV], time_pre[MAXV];
int num_time_path[MAXV];
void Dijkstra_dis(int s) {
fill(d, d + MAXV, INF);
memset(vis, false, sizeof(vis));
fill(Time,Time+MAXV,INF);
d[s] = 0;
Time[s] = 0;
for (int i = 0; i < n; i++) {
dis_pre[i] = i;
}
for (int i = 0; i < n; i++) {
int u = -1, MIN = INF;
for (int j = 0; j < n; j++) {
if (!vis[j] && d[j] < MIN) {
u = j;
MIN = d[j];
}
}
if (u == -1) return;
vis[u] = true;
for (int v = 0; v < n; v++) {
if (!vis[v] && G[u][v] != INF) {
if (G[u][v] + d[u] < d[v]) { //最短距离更小,更新
d[v] = G[u][v] + d[u];//更新最短距离
dis_pre[v] = u;
Time[v] = Time[u] + T[u][v];
} else if (G[u][v] + d[u] == d[v]) { //最短距离相等,考查时间
if (T[u][v] + Time[u] < Time[v]) { //更新时间
Time[v] = Time[u] + T[u][v];
dis_pre[v] = u; //前结点加入u
}
}
}
}
}
}
void Dijkstra_time(int s) { //第一标尺时间,第二标尺顶点数
memset(vis, false, sizeof(vis));
fill(Time, Time + MAXV, INF);
Time[s] = 0;
for (int i = 0; i < n; i++) {
int u = -1, MIN = INF;
for (int j = 0; j < n; j++) {
if (!vis[j] && Time[j] < MIN) {
u = j;
MIN = Time[j];
}
}
if (u == -1) return;
vis[u] = true;
for (int v = 0; v < n; v++) {
if (!vis[v] && T[u][v] != INF) {
if (T[u][v] + Time[u] < Time[v]) { //最短时间更小,更新
Time[v] = T[u][v] + Time[u];
time_pre[v] = u;
num_time_path[v] = num_time_path[u] + 1;
} else if (T[u][v] + Time[u] == Time[v]) { //最短时间相等,考查顶点数
if (num_time_path[u] + 1 < num_time_path[v]) {
time_pre[v] = u;
num_time_path[v] = num_time_path[u] + 1;
}
}
}
}
}
}
int num = 0;
void DFS_dis(int v) {
dis_path.push_back(v);
if (v == st) return;
DFS_dis(dis_pre[v]);
}
void DFS_time(int v) {
time_path.push_back(v);
if (v == st) return;
DFS_time(time_pre[v]);
}
int main() {
fill(G[0], G[0] + MAXV * MAXV, INF);
fill(T[0], T[0] + MAXV * MAXV, INF);
scanf("%d%d", &n, &m);
for (int i = 0; i < m; i++) {
int u, v;
int one_way;
int time, length;
scanf("%d%d%d%d%d", &u, &v, &one_way, &length, &time);
if (one_way != 1) {
G[u][v] = G[v][u] = length;
T[u][v] = T[v][u] = time;
} else {
G[u][v] = length;
T[u][v] = time;
}
}
scanf("%d%d", &st, &ed);
Dijkstra_dis(st);
DFS_dis(ed);
Dijkstra_time(st);
DFS_time(ed);
printf("Distance = %d", d[ed]);
if (dis_path == time_path) {
printf("; Time = %d: ", Time[ed]);
} else {
printf(": ");
for (int i = dis_path.size() - 1; i >= 0; i--) {
printf("%d", dis_path[i]);
if (i != 0) printf(" -> ");
}
printf("\nTime = %d: ", Time[ed]);
}
for (int i = time_path.size() - 1; i >= 0; i--) {
printf("%d", time_path[i]);
if (i != 0) printf(" -> ");
}
return 0;
}