CODE[VS]1020 孪生蜘蛛

题目: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;
}

猜你喜欢

转载自blog.csdn.net/QQ604666459/article/details/77933378
今日推荐