zoj 3497 Mistwald 矩阵快速幂

本文探讨了矩阵A^P中元素A[i][j]表示从i到j长度为P的路径条数的概念,并通过实例展示了矩阵相乘如何反映路径连接情况,与Floyd算法在寻找最短路径问题上的联系。文中提供了矩阵操作的C++代码实现,包括初始化、矩阵乘法、矩阵幂运算等关键步骤,旨在解决特定类型的路径问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

知道了矩阵的新作用,矩阵A^P,A[i][j]的数值是从i到j长度为P的路径条数,矩阵相乘如果A[i][k为1,B[k][j]为1,A[i][j] 必然>=1,表明以k为桥梁将i和j连接起来,和floyd算法本质上是一致的。

传送门:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4320


#include <stdio.h>
#include <string.h>
#include <stdlib.h>


int len_Matrix;
int Mod;

struct Matrix{
    int M[35][35];
};

void Init_Matrix(Matrix * tmp){
    for(int i=0;i<len_Matrix;i++){
        for(int j=0;j<len_Matrix;j++){
            tmp -> M[i][j] = 0;
        }
    }
    //tmp -> M[0][0] = 1;tmp -> M[0][2] = 1;tmp -> M[0][3] = 1;
    //tmp -> M[1][0] = 1;tmp -> M[2][1] = 1;tmp -> M[3][2] = 1;
}

Matrix multiply(Matrix a1,Matrix a2){
    Matrix ans;
    for(int i=0;i<len_Matrix-1;i++){
        for(int j=0;j<len_Matrix;j++){
            ans.M[i][j] = 0;
            for(int k=0;k<len_Matrix-1;k++){
               //ans.M[i][j] = (a1.M[i][k]*a2.M[k][j]+ans.M[i][j])%Mod; 
               if(a1.M[i][k]*a2.M[k][j]){
                    ans.M[i][j] = 1; 
                }
            }
        }
    }
    return ans;
}

Matrix Pow(Matrix tmp,int nl){
    Matrix ans ;
    for(int i=0;i<len_Matrix;i++){
        for(int j=0;j<len_Matrix;j++){
            if(i==j)ans.M[i][j] = 1;
            else ans.M[i][j] = 0;
        }
    }
    while(nl){
        if(nl&1){
            ans = multiply(ans,tmp);
        }
        tmp = multiply(tmp,tmp);
        nl /= 2;
    }
    return ans;
}

void Input(){
    int T;
    scanf("%d",&T);
    while(T--){
        int n,m;
        scanf("%d %d",&n,&m);
        getchar();
        len_Matrix = n * m;
        Matrix tmp;
        Init_Matrix(&tmp);
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                int x1,y1,x2,y2,x3,y3,x4,y4;
                scanf("((%d,%d),(%d,%d),(%d,%d),(%d,%d))",&x1,&y1,&x2,&y2,&x3,&y3,&x4,&y4);
                tmp.M[i*m+j][(x1-1)*m+(y1-1)] = 1;
                tmp.M[i*m+j][(x2-1)*m+(y2-1)] = 1;
                tmp.M[i*m+j][(x3-1)*m+(y3-1)] = 1;
                tmp.M[i*m+j][(x4-1)*m+(y4-1)] = 1;
                getchar();
            }
        }
        int n1;
        scanf("%d",&n1);
        for(int i=0;i<n1;i++){
            int k;
            scanf("%d",&k);
            Matrix ans = Pow(tmp,k);
            int con = 0;
            for(int j=0;j<len_Matrix;j++){
                if(ans.M[0][j])con++;
            }
            if(!ans.M[0][len_Matrix-1]){
                puts("False");
            }
            else if(con==1){
                puts("True");
            }
            else 
                puts("Maybe");
        }
        puts("");
    }
}

void File(){
    freopen("a.in","r",stdin);
    freopen("a.out","w",stdout);
}

int main(void){
    //File();
    Input();
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值