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 }

 

posted @ 2017-10-07 14:30  Leohh  阅读(267)  评论(0编辑  收藏  举报