[USACO07NOV]牛欄Cow Hurdles

題目描述

Farmer John 想讓她的奶牛準備郡級跳躍比賽,貝茜和她的夥伴們正在練習跨欄。她們很累,所以她們想消耗最少的能量來跨欄。 顯然,對於一頭奶牛跳過幾個矮欄是很容易的,但是高欄卻很難。於是,奶牛們總是關心路徑上最高的欄的高度。 奶牛的訓練場中有 N (1 ≤ N ≤ 300) 個站臺,分別標記爲1..N。所有站臺之間有M (1 ≤ M ≤ 25,000)條單向路徑,第i條路經是從站臺Si開始,到站臺Ei,其中最高的欄的高度爲Hi (1 ≤ Hi ≤ 1,000,000)。無論如何跑,奶牛們都要跨欄。 奶牛們有 T (1 ≤ T ≤ 40,000) 個訓練任務要完成。第 i 個任務包含兩個數字 Ai 和 Bi (1 ≤ Ai ≤ N; 1 ≤ Bi ≤ N),表示奶牛必須從站臺Ai跑到站臺Bi,可以路過別的站臺。奶牛們想找一條路徑從站臺Ai到站臺Bi,使路徑上最高的欄的高度最小。 你的任務就是寫一個程序,計算出路徑上最高的欄的高度的最小值。

輸入格式

行 1: 兩個整數 N, M, T

行 2..M+1: 行 i+1 包含三個整數 Si , Ei , Hi

行 M+2..M+T+1: 行 i+M+1 包含兩個整數,表示任務i的起始站臺和目標站臺: Ai , Bi

輸出格式

行 1..T: 行 i 爲一個整數,表示任務i路徑上最高的欄的高度的最小值。如果無法到達,輸出 -1。


我們可以用Floyd在一般有向圖上dp。

設dp(u,v)爲u到v路徑上的最高高度的最小值。那麼根據Floyd的做法,我們枚舉中間點k:

\[ dp[u][v]=Min(Max(dp[u][k],dp[k][v])) \]

時間複雜度爲O(N^3)

#include<iostream>
#include<cstring>
#include<cstdio>
#define maxn 301
using namespace std;
int n,m,t;
inline int read(){
    register int x(0),f(1); register char c(getchar());
    while(c<'0'||'9'<c){ if(c=='-') f=-1; c=getchar(); }
    while('0'<=c&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    return x*f;
}

int dp[maxn][maxn];
inline void Floyd(){
    for(register int k=1;k<=n;k++){
        for(register int i=1;i<=n;i++){
            for(register int j=1;j<=n;j++) if(i!=j&&dp[i][j]>max(dp[i][k],dp[k][j])){
                dp[i][j]=max(dp[i][k],dp[k][j]);
            }
        }
    }
}

int main(){
    memset(dp,0x3f3f3f3f,sizeof dp);
    n=read(),m=read(),t=read();
    for(register int i=1;i<=m;i++){
        int u=read(),v=read();
        dp[u][v]=read();
    }

    for(register int i=1;i<=n;i++) dp[i][i]=0;
    Floyd();
    for(register int i=1;i<=t;i++){
        int u=read(),v=read();
        printf("%d\n",dp[u][v]==0x3f3f3f3f?-1:dp[u][v]);
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章