BZOJ 1641 [Usaco2007 Nov]Cow Hurdles 奶牛跨栏:新版floyd【路径上最大边最小】
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1641
题意:
给你一个有向图,n个点(n <= 300),m条边,边权为h[i]。
t个询问(a,b)。让你找一条从a到b的路径,使路径上最大的边最小,输出这个最小值。
题解:
新版floyd。
dis[a][b]表示从a到b的路径中,最大边的最小值。
分别枚举k,i,j,然后取最小:
dis[i][j] = min(dis[i][j], max(dis[i][k],dis[k][j]))
dis[a][b]即为答案。
AC Code:
1 #include <iostream> 2 #include <stdio.h> 3 #include <string.h> 4 #define MAX_N 305 5 #define INF 10000000 6 7 using namespace std; 8 9 int n,m,t; 10 int dis[MAX_N][MAX_N]; 11 12 void read() 13 { 14 scanf("%d%d%d",&n,&m,&t); 15 memset(dis,0x3f,sizeof(dis)); 16 int a,b,h; 17 for(int i=0;i<m;i++) 18 { 19 scanf("%d%d%d",&a,&b,&h); 20 dis[a][b]=min(dis[a][b],h); 21 } 22 } 23 24 void floyd() 25 { 26 for(int k=1;k<=n;k++) 27 { 28 for(int i=1;i<=n;i++) 29 { 30 for(int j=1;j<=n;j++) 31 { 32 if(i!=j && j!=k && i!=k) 33 { 34 dis[i][j]=min(dis[i][j],max(dis[i][k],dis[k][j])); 35 } 36 } 37 } 38 } 39 } 40 41 void work() 42 { 43 floyd(); 44 int a,b; 45 for(int i=0;i<t;i++) 46 { 47 scanf("%d%d",&a,&b); 48 if(dis[a][b]>INF) printf("-1\n"); 49 else printf("%d\n",dis[a][b]); 50 } 51 } 52 53 int main() 54 { 55 read(); 56 work(); 57 }