矩阵快速幂 ZOJ 3497 Mistwald

题目传送门

题意:看似给了一个迷宫,每个点能传送到4个地方,问在P时间能否到达终点

分析:其实是一个有向图,可以用邻接矩阵存图,连乘P次看是否能从1到n*m,和floyd的传递背包思想一样

#include <bits/stdc++.h>

int tot;
struct Mat {
    int m[30][30];
    Mat() {
        memset (m, 0, sizeof (m));
    }
    void init() {
        for (int i=1; i<=tot; ++i) {
            m[i][i] = 1;
        }
    }
};
Mat operator * (const Mat &a, const Mat &b) {
    Mat ret;
    for (int i=1; i<=tot; ++i) {
        for (int j=1; j<=tot; ++j) {
            for (int k=1; k<=tot; ++k) {
                int &r = ret.m[i][j];
                r = r | (a.m[i][k] & b.m[k][j]);
            }
        }
    }
    return ret;
}
Mat operator ^ (Mat x, int n) {
    Mat ret; ret.init ();
    while (n) {
        if (n & 1) {
            ret = ret * x;
        }
        x = x * x;
        n >>= 1;
    }
    return ret;
}
int x[4], y[4];
int m, n;

int main() {
    int T; scanf ("%d", &T);
    while (T--) {
        scanf ("%d%d
", &m, &n);
        tot = m * n;
        Mat mat;
        for (int i=1; i<=m; ++i) {
            for (int j=1; j<=n; ++j) {
                scanf ("((%d,%d),(%d,%d),(%d,%d),(%d,%d))", &x[0], &y[0], &x[1], &y[1], &x[2], &y[2], &x[3], &y[3]);
                int pos = (i - 1) * n + j;
                if (pos == tot) {
                    continue;
                }
                for (int i=0; i<4; ++i) {
                    mat.m[pos][(x[i]-1)*n+y[i]] = 1;
                }
                getchar ();
            }
        }
        int q; scanf ("%d", &q);
        while (q--) {
            int t; scanf ("%d", &t);
            if (t == 0) {
                if (tot == 1) {
                    puts ("True");
                } else {
                    puts ("False");
                }
            } else {
                Mat ans = mat ^ t;
                if (!ans.m[1][tot]) {
                    puts ("False");
                } else {
                    int i;
                    for (i=1; i<=tot; ++i) {
                        if (ans.m[1][i]) {
                            break;
                        }
                    }
                    if (i == tot) {
                        puts ("True");
                    } else {
                        puts ("Maybe");
                    }
                }
            }
        }
        puts ("");
    }

    return 0;
}

  

原文地址:https://www.cnblogs.com/Running-Time/p/5323980.html