Description
有
n
n
n 个城市,编号从
1
∼
n
1 \sim n
1∼n 。小明的家所在城市编号为
x
(
1
≤
x
≤
n
)
x(1 \leq x \leq n)
x(1≤x≤n) 。两个城市
u
u
u 和
v
v
v 之间存在路径长度为
w
w
w 的单向路
<
u
,
v
>
。
<u, v>。
<u,v>。 小 明想知道分别从
n
n
n 个城市出发,到达小明所在城市并返回的最短路径中最长的是多少?
Input Data
第一行是一个整数
T
(
1
≤
T
≤
100
)
T(1 \leq T \leq 100)
T(1≤T≤100) ,表示样例的个数。
输入的第一行包含 3 个整数,
n
,
e
,
x
(
1
≤
n
≤
1000
,
1
≤
e
≤
10000
,
1
≤
x
≤
n
)
n, e, x(1 \leq n \leq 1000,1 \leq e \leq 10000,1 \leq x \leq n)
n,e,x(1≤n≤1000,1≤e≤10000,1≤x≤n) ,分别表示城市数量,路径数量以及小明所在城 市编号。
随后的
e
e
e 行,每行是一条路径,包含三个整数
u
,
v
,
w
(
1
≤
u
,
v
≤
n
,
1
≤
w
≤
1000
)
u, v, w(1 \leq u, v \leq n, 1 \leq w \leq 1000)
u,v,w(1≤u,v≤n,1≤w≤1000) 。输入保证一定有解。
Output Data
每行输出一个样例的结果。
Sample Input
1
4 7 2
1 2 7
1 3 2
2 3 1
3 2 2
3 4 5
2 1 3
4 2 3
Sample Output
9
Tips: 分别建立正图和反图,对于x点,跑两次Dijkstra,求出该点到其他点的距离,然后求这两次的最小距离之和的最大值。
struct Node {
int x, z;
bool operator < (const Node& rhs) const {
return z > rhs.z;
}
};
void solve() {
int n, e, s;
cin >> n >> e >> s;
vector<vector<pair<int,int>>> g(n + 1), h(n + 1);
while (e--) {
int u, v, w;
cin >> u >> v >> w;
g[u].push_back(make_pair(v, w));
h[v].push_back(make_pair(u, w));
}
priority_queue<Node> pq;
pq.push(Node{s, 0});
vector<int> dis(n + 1, INT_MAX), vis(n + 1, 0), dis2(dis), vis2(vis);
dis[s] = 0;
while (!pq.empty()) {
auto t = pq.top();
int x = t.x;
pq.pop();
if (vis[x]) continue;
vis[x] = 1;
for (int i = 0; i < g[x].size(); i++) {
auto y = g[x][i].first, z = g[x][i].second;
if (dis[y] > dis[x] + z) {
dis[y] = dis[x] + z;
if (!vis[y]) {
pq.push(Node{y, dis[y]});
}
}
}
}
dis2[s] = 0;
pq.push(Node{s, 0});
while (!pq.empty()) {
auto t = pq.top();
pq.pop();
int x = t.x;
if (vis2[x]) continue;
vis2[x] = 1;
for (int i = 0; i < h[x].size(); i++) {
auto y = h[x][i].first, z = h[x][i].second;
if (dis2[y] > dis2[x] + z) {
dis2[y] = dis2[x] + z;
if (!vis2[y]) {
pq.push(Node{y, dis2[y]});
}
}
}
}
int ans = 0;
for (int i = 1; i <= n; i++) {
ans = max(dis[i] + dis2[i], ans);
}
cout << ans << "\n";
}