【题解】 [USACO 2007 NOV] Cow Hurdles S
题目描述
题目大意
给定一个 \(n\) 点 \(m\) 边的带权有向图,以及 \(t\) 次询问。每次询问给出图中两个节点,求出两个节点的路径上最大的边权的最小值,如果无法到达,输出“-1”。
思路
该题主要考察:Floyd算法思想。
Floyd原本是枚举中转站,通过中转站进行松弛,求最短路。
这道题是Floyd的变式。首先,原松弛操作是 dis[u][v] = min(dis[u][v], dis[u][k] + dis[k][v];,其中 \(k\) 为枚举的中转站。那么,可以将原松弛操作改为 dis[u][v] = min(dis[u][v], max(dis[u][k], dis[k][v]));,就可以求出两个节点的路径上最大的边权的最小值。
代码
#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> PII;
#define x first
#define y second
const int N = 305, M = 3e4 + 5, INF = 0x3f3f3f3f;
int n, m, k;
int a[N][N];
void Floyd()
{
for (int k = 1; k <= n; k ++ )
for (int i = 1; i <= n; i ++ )
for (int j = 1; j <= n; j ++ )
a[i][j] = min(a[i][j], max(a[i][k], a[k][j])); // 新松弛操作
}
int main()
{
scanf("%d%d%d", &n, &m, &k);
memset(a, 0x3f, sizeof a);
while (m -- )
{
int u, v, w; scanf("%d%d%d", &u, &v, &w);
a[u][v] = w; // 建单向边
}
Floyd();
while (k -- )
{
int st, ed; scanf("%d%d", &st, &ed);
if (a[st][ed] > INF / 2) // 判断是否可达
puts("-1");
else
printf("%d\n", a[st][ed]);
}
return 0;
}

浙公网安备 33010602011771号