题目:http://codevs.cn/problem/1020/
思路:首先计算各通道间的最短时间,使用(a, b) 和(b, c)的时间,来更新(a, c)间的时间。然后枚举所有的x1, x2组合,来计算任意点C到X1,X2的最短时间,并记录最长的最短时间,即为最坏的情况。在所有组合最坏情况中,找寻时间最短的组合。
题解:
/* 1020 孪生蜘蛛 */
#include <stdio.h>
#define DEBUG
#define MAXN 101 /* 最大通道数 */
int n; /* 通道数 */
int roads[MAXN][MAXN]; /* 通道连接矩阵 */
int x1, x2; /* 蜘蛛所在位置 */
/* 更新通路连通时间 */
void update_time(int a, int b, int t){
if(0 == roads[a][b] || t < roads[a][b]){
roads[a][b] = t;
roads[b][a] = t;
}
}
/* 计算完整通路连通时间 */
void cal_time() {
int a, b, c, t1, t2;
for(a = 1; a <= n; a++){
/* 遍历所有与a直接相连的通道b */
for(b = 1; b <= n; b++){
t1 = roads[a][b];
if(t1 > 0){
/* 遍历所有与b相连的通道c */
for(c = 1; c <= n; c++){
t2 = roads[b][c];
if(t2 > 0 && a != c){
/* 更新a与c之间的连通时间 */
update_time(a, c, t1 + t2);
}
}/* 遍历通道c结束 */
}
}/* 遍历通道b结束 */
}/* 遍历通道a结束 */
}
/* 获取最长时间 */
int get_maxt(int a, int b){
int c;
int t, maxt;
maxt = 0;
for(c = 1; c <= n; c++){
/* c到a或b的最短时间 */
t = (roads[a][c] < roads[b][c]) ? roads[a][c] : roads[b][c];
/* 记录最短时间里的最长时间 */
if(maxt == 0 || maxt < t){
maxt = t;
}
}
return maxt;
}
/* 计算最优点 */
void cal_x1_x2(){
int i, j, t, mint;
mint = 0;
for(i = 1; i <= n; i++){
for(j = i + 1; j <= n; j++){
/* 计算最长时间 */
t = get_maxt(i, j);
/* 记录最短的最长时间 */
if(mint == 0){
mint = t;
x1 = i;
x2 = j;
}
else if(mint > t){
mint = t;
x1 = i;
x2 = j;
}
}
}
}
/* 主函数入口 */
int main(int argc, char *argv[]) {
int i; /* 索引值 */
int a, b, t; /* 通道a, b和时间t */
#ifdef DEBUG
FILE *fp;
if(NULL == (fp = fopen("data.txt", "r"))){
return 1;
}
#endif
/* 获取通道数 */
#ifdef DEBUG
fscanf(fp, "%d", &n);
#else
scanf("%d", &n);
#endif
/* 初始化通路时间 */
for(a = 1; a <= n; a++){
for(b = 1; b <= n; b++){
roads[a][b] = 0;
}
}
/* 获取通道连通时间 */
do{
a = b = t = 0;
#ifdef DEBUG
fscanf(fp, "%d %d %d", &a, &b, &t);
#else
scanf("%d %d %d", &a, &b, &t);
#endif
if(a != 0 && b != 0 && t != 0){
roads[a][b] = t;
roads[b][a] = t;
}
}while(a != 0 || b != 0 || t != 0);
/* 计算每个通道间的连通时间 */
cal_time();
/* 测试 - 打印连通矩阵 */
/*
for(a = 0; a <= n; a++){
printf("%-4d", a);
}
printf("\n");
for(a = 1; a <= n; a++){
printf("%-4d", a);
for(b = 1; b <= n; b++){
printf("%-4d", roads[a][b]);
}
printf("\n");
}
*/
/* 计算x1, x2的位置 */
cal_x1_x2();
/* 输出结果 */
printf("%d %d", x1, x2);
#ifdef DEBUG
fclose(fp);
#endif
return 0;
}