题目大意:由n位股票经纪人传播股票(编号1到n),每位股票经纪人都可以向m位同事传播(经纪人之间互为同事,但传播是单向的),传播时需花费t个时间单位(如果2号和3号都是1号经纪人的同事,1号向2号传播需要5个时间单位,向3号传播需要4个时间单位,那么1号可以在5个时间单位的时间内向2号和3号同时传播);现在告诉你每位经纪人和其同事的信息(信息包括同事的编号和传播需要的时间单位),问你想要在最短的时间内向所有人传播信息的话,应该选择哪位经纪人,同时求出向所有人传播所需要的时间。如果经纪人不能全部传播完,输出disjoint。
分析:我们可以先找出每一位经纪人向其他所有人传播的最短路,然后在每一位经纪人传播时间中找出所需时间最多的那个时间(类似于木桶效应,一个人可以向其他人传播完,用的最少时间就是它向这些人传播所需的最大时间),然后在这些时间中找出最小的输出即可。如果找不出这个最少的时间,那么就说明他们之间不能全部传播,输出disjoint就行了。
实现代码如下:
#include <cstdio>
#include <iostream>
using namespace std;
#define INF 999999999
int map[105][105];
int n,m;
void floyd()
{
int i,j,k,sum;
int ans=INF,num;
bool flag[105];
for(k=1;k<=n;k++)
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
if(map[i][j]>map[i][k]+map[k][j])
map[i][j]=map[i][k]+map[k][j];
for(i=1;i<=n;i++)
{
sum=0;
for(j=1;j<=n;j++)
if(sum<map[i][j]&&i!=j)
sum=map[i][j];
if(ans>sum)
{
ans=sum;
num=i;
}
}
if(ans<INF) printf("%d %d\n",num,ans);
else puts("disjoint");
}
int main()
{
while(scanf("%d",&n)&&n)
{
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
map[i][j]=(i==j)?0:INF;
for(int i=1;i<=n;i++)
{
scanf("%d",&m);
for(int j=1;j<=m;j++)
{
int x,t;
scanf("%d%d",&x,&t);
map[i][x]=t;
}
}
floyd();
}
return 0;
}