【题解】[Usaco2008 Oct]牧场行走

拿到题我一看题,大概是考我们无向图(尽管题目说的是树)的最短路径吧
正当我打到一半时,dalao智慧草(这个人可是个神仙)忍不住了:
“floyd时间复杂度O(n^3)再看看数据范围n=10^3时肯定得超时,这题正解是LCA不倍增也行”
本菜鸡偏就不信,我就要用floyd做,哼哼。
很快敲完了一个模板,代码:

#include <iostream>
using namespace std;
int n, m, x, y, z;
int edge[1001][1001];
int main() {
    cin >> n >> m;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            edge[i][j] = (i == j) ? 0 : 0x3f3f3f3f;
        }
    }
    for (int i = 1; i <= n - 1; i++) {
        cin >> x >> y >> z;
        edge[x][y] = edge[y][x] = z;
    }
    for (int k = 1; k <= n; k++) {
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                edge[i][j] = min(edge[i][j], edge[i][k] + edge[k][j]);
            }
        }
    }
    for (int i = 1; i <= m; i++) {
        cin >> x >> y;
        cout << edge[x][y] << endl;
    }
    return 0;
}

交上去80,海星
然后就是优化了
首先第i个节点必须不是第k个节点,不然自己到自己吃饱撑着(i!=k)
其次第i个节点到第k个节点必须有边,毕竟这些奶牛的关系是像树一样的(t!=inf)
之后就是利用矩阵的对称性,只使用下三角(可有可无)
优化完毕(因为我只使用了下三角,所以我的输出得注意一下)
AC代码(160ms挺慢的):

#include <cstdio>
int n, m, x, y, z;
int edge[1001][1001];
int min(int x, int y) { return (x < y) ? x : y; }
int main() {
    scanf("%d %d", &n, &m);
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            edge[i][j] = (i == j) ? 0 : 0x3f3f3f3f;
        }
    }
    for (int i = 1; i <= n - 1; i++) {
        scanf("%d %d %d", &x, &y, &z);
        edge[x][y] = edge[y][x] = z;
    }
    for (int k = 1; k <= n; k++) {
        for (int i = 1; i <= n; i++) {
            if (k != i) {
                int t = (k < i) ? edge[i][k] : edge[k][i];
                if (t == 0x3f3f3f3f)
                    continue;
                for (int j = 1; j <= min(k, i); j++) {
                    edge[i][j] = min(edge[i][j], t + edge[k][j]);
                }
                for (int j = k + 1; j <= i; j++) {
                    edge[i][j] = min(edge[i][j], t + edge[j][k]);
                }
            }
        }
    }
    for (int i = 1; i <= m; i++) {
        scanf("%d %d", &x, &y);
        printf("%d\n", edge[x][y] == 0x3f3f3f3f ? edge[y][x] : edge[x][y]);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/fox-nest/p/12209183.html