思路:单源最短路,套用spfa模板,这里需要构造逆向边,调用两次spfa。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
const int N = 10009;
const int inf = 1<<30;
typedef struct node {
int v, w, next;
}node;
node p1[N], p2[N];
bool vis[N];
int head1[N], head2[N], dis1[N], dis2[N];
queue <int> que;
int n, m, x;
void add_edge(int u, int v, int w, int i) {
p1[i].v = v;
p1[i].w = w;
p1[i].next = head1[u];
head1[u] = i;
p2[i].v = u;
p2[i].w = w;
p2[i].next = head2[v];
head2[v] = i;
}
void spfa(int dis[], node p[], int head[]) {
memset(vis, 0, sizeof(vis));
while (!que.empty()) que.pop();
int i, u, v;
for (i = 1; i <= n; ++i)
dis[i] = inf;
dis[x] = 0;
vis[x] = 1;
que.push(x);
while (!que.empty()) {
u = que.front();
que.pop();
for (i = head[u]; i != -1; i = p[i].next) {
v = p[i].v;
if (dis[v] > dis[u] + p[i].w) {
dis[v] = dis[u] + p[i].w;
if (!vis[v]) {
vis[v] = true;
que.push(v);
}
}
}
vis[u] = false;
}
}
int main()
{
int i, u, v, w;
while (scanf("%d %d %d", &n, &m, &x) != EOF) {
memset(head1, -1, sizeof(head1));
memset(head2, -1, sizeof(head2));
for (i = 0; i < m; ++i) {
scanf("%d %d %d", &u, &v, &w);
add_edge(u, v, w, i);
}
int max_t = -1;
spfa(dis1, p1, head1);
spfa(dis2, p2, head2);
for (i = 1; i <= n; ++i) {
if (max_t < dis1[i] + dis2[i])
max_t = dis1[i] + dis2[i];
}
printf("%d\n", max_t);
}
return 0;
}