题目大意:输入一个有向图,n个顶点表示n个人,每个人可以向相连的人散播消息,相连的有向边表示需要的时间。而且在一定时间内,消息是“同时”传播到所有相邻的人那里。求消息从哪个人开始传播,所需要的时间最短,输出此人编号和最短时间。当图不连通即无论怎样都有人得不到消息时,输出“disjoint”
思路:floyd算法求出每个人到其他相邻各人的最短时间,对每个人求出到其他各人最短时间里的最长时间,因为只有这样,才能保证从此人出发的时候把消息传达到了所有人那里。找这n个人里最长时间最短的那个,就是答案。
#include<stdio.h>
int n, map[101][101];//邻接矩阵存储,floyd之后变成了最短路矩阵
void init();
void read();
void floyd();
int main(){
int i;
while(scanf("%d", &n), n){
init();
read();
floyd();
}
return 0;
}
void floyd(){
int i, j, k, path, min, v;
for(k = 1; k <= n; k++)//k作为从i到j的中间点
for(i = 1; i <= n; i++)
for(j = 1; j <= n; j++)
map[i][j] = map[i][j] < (map[i][k] + map[k][j]) ? map[i][j] : (map[i][k] + map[k][j]);
min = 65535;
for(i = 1; i <= n; i++){//穷举n个顶点
path = 0;
for(j = 1; j <= n; j++){//求第i个点到其他各点的最短路中的最大值
if(path < map[i][j]){
path = map[i][j];
}
}
if(min > path){//在这n次循环里记录最小值
min = path;
v = i;//记录是从谁那里传播来的
}
}
if(min < 65535)
printf("%d %d\n", v, min);
else
printf("disjoint\n");
}
void init(){
int i, j;
for(i = 1; i <= n; i++){
for(j = 1; j <= n; j++){
if(i == j)
map[i][j] = 0;
else
map[i][j] = 65535;
}
}
}
void read(){
int num, i, j, k, w;
for(i = 1; i <= n; i++){
scanf("%d", &num);
for(j = 0; j < num; j++){
scanf("%d %d", &k, &w);
map[i][k] = w;
}
}
}