题意:输入一个图,边权包括路径长度,要消耗的时间。输出最短路径,多条则输出耗时最短的,输出耗时最多的路径,多条则输出经过点最少的。
思路:spfa跑两下就好。
代码
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <queue>
#include <climits>
using namespace std;
const int MAX_N = 510;
struct Data {
int to, d, t, nxt;
}e[MAX_N*MAX_N];
int head[MAX_N], cnt = 1;
void ins(int u, int v, int d, int t) {
cnt++;
e[cnt].to = v; e[cnt].d = d; e[cnt].t = t;
e[cnt].nxt = head[u]; head[u] = cnt;
}
int N, M, o, d, t, u, v;
int dis[MAX_N], tim[MAX_N], from1[MAX_N], from2[MAX_N], ct[MAX_N], inq[MAX_N];
int mind, mint;
void spfa1(int r, int d) {
for (int i = 0; i < N; i++) {
dis[i] = tim[i] = INT_MAX;
from1[i] = -1;
inq[i] = 0;
}
dis[r] = tim[r] = 0;
queue<int> q1;
q1.push(r); inq[r] = 1;
while (!q1.empty()) {
int tp = q1.front(); q1.pop();
for (int i = head[tp]; i; i = e[i].nxt) {
if (dis[tp] + e[i].d < dis[e[i].to]) {
dis[e[i].to] = dis[tp] + e[i].d;
tim[e[i].to] = tim[tp] + e[i].t;
from1[e[i].to] = tp;
if (!inq[e[i].to]) {
inq[e[i].to] = 1;
q1.push(e[i].to);
}
} else if (dis[tp] + e[i].d == dis[e[i].to]) {
if (tim[tp] + e[i].t < tim[e[i].to]) {
tim[e[i].to] = tim[tp] + e[i].t;
from1[e[i].to] = tp;
if (!inq[e[i].to]) {
inq[e[i].to] = 1;
q1.push(e[i].to);
}
}
}
}
inq[tp] = 0;
}
mind = dis[d];
}
void spfa2(int r, int d) {
for (int i = 0; i < N; i++) {
tim[i] = ct[i] = INT_MAX;
from2[i] = -1;
inq[i] = 0;
}
tim[r] = 0; ct[r] = 0;
queue<int> q1;
q1.push(r); inq[r] = 1;
while (!q1.empty()) {
int tp = q1.front(); q1.pop();
for (int i = head[tp]; i; i = e[i].nxt) {
if (tim[tp] + e[i].t < tim[e[i].to]) {
tim[e[i].to] = tim[tp] + e[i].t;
from2[e[i].to] = tp;
ct[e[i].to] = ct[tp] + 1;
if (!inq[e[i].to]) {
inq[e[i].to] = 1;
q1.push(e[i].to);
}
} else if (tim[tp] + e[i].t == tim[e[i].to]) {
if (ct[tp] + 1 < ct[e[i].to]) {
ct[e[i].to] = ct[tp] + 1;
from2[e[i].to] = tp;
if (!inq[e[i].to]) {
inq[e[i].to] = 1;
q1.push(e[i].to);
}
}
}
}
inq[tp] = 0;
}
mint = tim[d];
}
int ro1[MAX_N], len1 = 0;
void road1(int d) {
if (d == -1) return ;
road1(from1[d]);
ro1[len1++] = d;
}
int ro2[MAX_N], len2 = 0;
void road2(int d) {
if (d == -1) return ;
road2(from2[d]);
ro2[len2++] = d;
}
bool isU() {
if (len1 != len2) return false;
for (int i = 0; i < len1; i++) {
if (ro1[i] != ro2[i]) return false;
}
return true;
}
int main() {
// freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
scanf("%d %d", &N, &M);
for (int i = 0; i < M; i++) {
scanf("%d %d %d %d %d", &u, &v, &o, &d, &t);
if (o == 1) {
ins(u, v, d, t);
} else {
ins(u, v, d, t);
ins(v, u, d, t);
}
}
scanf("%d %d", &u, &v);
spfa1(u, v);
spfa2(u, v);
road1(v);
road2(v);
if (isU()) {
printf("Distance = %d; ", mind);
printf("Time = %d: ", mint);
for (int i = 0; i < len1; i++) {
if (i > 0) printf(" -> ");
printf("%d", ro1[i]);
if (i == len1-1) printf("\n");
}
} else {
printf("Distance = %d: ", mind);
for (int i = 0; i < len1; i++) {
if (i > 0) printf(" -> ");
printf("%d", ro1[i]);
if (i == len1-1) printf("\n");
}
printf("Time = %d: ", mint);
for (int i = 0; i < len2; i++) {
if (i > 0) printf(" -> ");
printf("%d", ro2[i]);
if (i == len2-1) printf("\n");
}
}
return 0;
}