题目链接:
http://acm.pku.edu.cn/JudgeOnline/problem?id=1125
理解题意最关键的一句话:
Your task will be to write a program that tells you which stockbroker to choose as your
starting point for the rumour, as well as the time it will take for the rumour to spread
throughout the stockbroker community. This duration is measured as the time needed for the
last person to receive the information.
本题 0测试 直接 编译提交AC三步到位!!!^_^~~~
//策略:
//先用Floyd算法求出从每一个顶点到其他所有顶点的最短路径的长度
//再保存每个顶点到其他所有顶点的最大距离到dist[]数组中
//找出数组的最小值
//如果最小值为Inf则存在不可到达顶点.否则输出该路径长度
#include <stdio.h>
#define Inf 1<<20
#define max_n 105
#define MIN(x,y) ((x) < (y) ? (x) : (y))
#define MAX(x,y) ((x) > (y) ? (x) : (y))
int arc[max_n][max_n];
int dist[max_n];
//k >= 1时:
//d(0)[i][j] = w[i][j];
//d(k)[i][j] = min(d(k - 1)[i][j],d[k - 1][i][k] + d[k - 1][k][j])
//也就是说:
//当中间顶点的最大序号从k - 1增加到k的时候
//(i,j)的距离是原来的距离与中间顶点的最大序号为k的2段(i,k),(k,j)的和的最小值
//其中这2段的中间顶点的最大序号为k - 1,因为对他们而已k是末端顶点
void Floyd(int n){
int i,j,k;
for(k = 1;k <= n;k++)
for(i = 1;i <= n;i++)
for(j = 1;j <= n;j++)
arc[i][j] = MIN(arc[i][j],arc[i][k] + arc[k][j]);
}
int main(){
int n;
while(scanf("%d",&n),n){
int i,j,k;
for(i = 1;i <= n;i++)
for(j = 1;j <= n;j++){
if(i == j)
arc[i][j] = 0;
else
arc[i][j] = Inf;
}
int u,cost;
for(i = 1;i <= n;i++){
scanf("%d",&k);
for(j = 1;j <= k;j++){
scanf("%d%d",&u,&cost);
arc[i][u] = cost;
}
}
Floyd(n);
int max_d;
for(i = 1;i <= n;i++){
max_d = -1;
for(j = 1;j <= n;j++)
max_d = MAX(max_d,arc[i][j]);
dist[i] = max_d;
}
int min_d = Inf,fastest;
for(i = 1;i <= n;i++)
//min_d = MIN(min_d,dist[i]);
if(dist[i] < min_d){
min_d = dist[i];
fastest = i;
}
if(min_d == Inf)
printf("disjoint/n");
else
printf("%d %d/n",fastest,min_d);
}
return 0;
}