HDU 2157 矩阵快速幂

在打牛客的时候碰到一道类似的题,我以为是图论题,结果看了题解,居然是一道矩阵快速幂的经典题。

哪个地方会直接用到矩阵快速幂,对,就是图论中求对应两个点长度为n的路径数,这是矩阵乘法在图论中的经典应用,其实就是用到了矩阵乘法的特殊性,因为矩阵乘法有三重循环,最里面的一层循环就是在枚举一个点k,i -> k -> j,那么从i -> j的路径数长度为m的条数就等于i-> k路径长度为n的路径数乘上k -> j路径长度为m - n的的路径条数,枚举的过程中全加起来,可以看到,这个过程和矩阵乘法的过程是一样的。

附上博客:https://blog.csdn.net/FlushHip/article/details/80068888

代码:

///#include<bits/stdc++.h>
///#include<unordered_map>
///#include<unordered_set>
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<queue>
#include<set>
#include<stack>
#include<map>
#include<new>
#include<vector>
#define MT(a,b) memset(a,b,sizeof(a));
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const double pai=acos(-1.0);
const double E=2.718281828459;
const long long mod=1000;
const int INF=0x3f3f3f3f;

int n,m,q,s,e;

struct node
{
    int num[25][25];
} maps,ans,ex;

struct node Matrix_mul(node a,node b)
{
    node c;
    memset(c.num,0,sizeof(c.num));
    for(int i=1; i<=n; i++)
        for(int j=1; j<=n; j++)
            for(int k=1; k<=n; k++)
                c.num[i][j]=(c.num[i][j]+a.num[i][k]*b.num[k][j]%mod)%mod;
    return c;
};

void power_Matrix(int k)
{
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
            ans.num[i][j]=0;
        ans.num[i][i]=1;
    }
    while(k)
    {
        if(k&1)
            ans=Matrix_mul(ans,ex);
        ex=Matrix_mul(ex,ex);
        k=k>>1;
    }
}

int main()
{
    while(scanf("%d %d",&n,&m)&&n+m)
    {
        memset(maps.num,0,sizeof(maps.num));
        while(m--)
        {
            scanf("%d %d",&s,&e);
            maps.num[s+1][e+1]=1;
        }
        scanf("%d",&q);
        while(q--)
        {
            ex=maps;
            scanf("%d %d %d",&s,&e,&m);
            power_Matrix(m);
            printf("%d\n",ans.num[s+1][e+1]);
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_42211531/article/details/85777935