POJ 1603: Risk

题目在此

解题思路:就是在给定的无向图上搜寻给定起点至给定终点间最短路径的问题。

恶心的输入案例,硬将输入拆成两半,把我这个资深强迫症患者折磨得要死。用 getchar/ungetc、cin.get()/cin.unget() 贡献若干次 TLE 后,终于成功……说服自己放弃。

代码:

#include <cstdio>
#include <cstring>

const int MAX = 21;
int countries[MAX][MAX];

int main() {
    int n, v, c = 1;
    while (scanf("%d", &n) != EOF) {
        // 构建邻接矩阵
        memset(countries, MAX, sizeof(countries));

        while (n--) {
            scanf("%d", &v);
            countries[1][v] = 1;
            countries[v][1] = 1;
        }

        for (int i = 2; i < 20; ++i) {
            scanf("%d", &n);
            while (n--) {
                scanf("%d", &v);
                countries[i][v] = 1;
                countries[v][i] = 1;
            }
        }

        // Floyd-Warshall 算法
        // 很直白的动规,原理见 wikipedia
        for (int k = 1; k < MAX; ++k) {
            for (int i = 1; i < MAX; ++i) {
                for (int j = 1; j < MAX; ++j) {
                    if (countries[i][k] + countries[k][j] < countries[i][j]) {
                        countries[i][j] = countries[i][k] + countries[k][j];
                    }
                }
            }
        }

        scanf("%d", &n);
        printf("Test Set #%d\n", c++);
        int s, e;
        while (n--) {
            scanf("%d%d", &s, &e);
            printf("%d to %d: %d\n", s, e, countries[s][e]);
        }
        printf("\n");
    }

    return 0;
}

你可能感兴趣的:(POJ 1603: Risk)