Southern African 2001 Stockbroker Grapevine /// Floyd oj1345

题目大意:

输入n 接下来n行

每行输入m 接下来m对a,b

若干个人之间会传播谣言,但每个人传播给其他人的速度都不一样,

问最快的传播路线(即耗时最短的)中最耗时的一个传播环节。

如果其中有人不在这个链中,则输出disjoin,否则输出最快的传播人和该条传播路线中的最慢的一个传播环节花费时间。

Sample Input
3
2 2 4 3 5
2 1 2 3 6
2 1 2 2 2
5
3 4 4 2 8 5 3
1 5 8
4 1 6 4 10 2 7 5 2
0
2 2 5 1 5
0
Sample Output

 3 2
 3 10

3
2 2 4 3 5
2 1 2 3 6
2 1 2 2 2

三个点

两对值(点1) 到点2用时4 到点3用时5
两对值(点2) 到点1用时2 到点3用时6
两对值(点3) 到点1用时2 到点2用时2

3 2

从点3出发用时最短 其中最长用时为2
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
int G[105][105];
int main()
{
    int n;
    while(~scanf("%d",&n)&&n)
    {
            memset(G,INF,sizeof(G));
            for(int i=1;i<=n;i++)
            {
                G[i][i]=0;
                int m; scanf("%d",&m);
                while(m--)
                {
                    int a,b; scanf("%d%d",&a,&b);
                    G[i][a]=min(G[i][a],b);
                }
            }

            for(int i=1;i<=n;i++)
                for(int j=1;j<=n;j++)
                    for(int k=1;k<=n;k++)
                    {
                        if(k==i||k==j||i==j) continue;
                        G[j][k]=min(G[j][k],G[j][i]+G[i][k]);
                    } /// Floyd求最短路
                    
            int minG=INF,maxG,index;
            for(int i=1;i<=n;i++)
            {
                maxG=0;
                for(int j=1;j<=n;j++)
                    maxG=max(maxG,G[i][j]); 
               /// 从i出发的最长用时 若为INF 说明该条有缺口

                if(minG>maxG) /// 得到最长用时中最短的一个 
                {
                    minG=maxG;
                    index=i;
                }
            }

            if(minG==INF) /// 说明整链有缺口
                printf("disjoint
");
            else
                printf("%d %d
",index,minG);
    }

    return 0;
}
View Code
原文地址:https://www.cnblogs.com/zquzjx/p/8606225.html