【题解】 [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;
}

posted @ 2024-08-22 21:20  _TJHtjh  阅读(14)  评论(0)    收藏  举报