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;
}