HDU 2157 How many ways??
離散數學中證明過這樣一個結論:
書上寫了一大堆,說人話 就是:
從u點到v點恰好經過k步的方案數,爲鄰接矩陣的k次冪得到的矩陣(假設是ans)中的元素ans[u][v]。
出題人比較友好,冪次比較小(k<20),不用矩陣快速冪也能過,但還是寫一下矩陣快速冪的代碼:
#include <bits/stdc++.h>
using namespace std;
const int N=22,mod=1000;
int n,m,x,y,k,q;
struct node
{
int m[N][N];
}s;
node mul(node s1,node s2) // 兩矩陣相乘
{
node ans;
memset(ans.m,0,sizeof(ans.m));
// 全部初始化爲0(結構體內不會自動初始化)
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
for(int k=0;k<n;k++)
ans.m[i][j]=(ans.m[i][j]+s1.m[i][k]*s2.m[k][j]%mod)%mod;
return ans;
}
node qpow(node a,int b) // 矩陣a的b次冪
{
node ans;
memset(ans.m,0,sizeof(ans.m));
for(int i=0;i<n;i++)
ans.m[i][i]=1; // ans初始化爲單位矩陣
while(b)
{
if(b&1)ans=mul(ans,a);
a=mul(a,a);
b/=2;
}
return ans;
}
int main()
{
ios::sync_with_stdio(false);
while(cin>>n>>m&&(n||m))
{
memset(s.m,0,sizeof(s.m));
for(int i=1;i<=m;i++)
{
cin>>x>>y;
s.m[x][y]=1; // 如果有重邊也只算一條路
}
cin>>q;
node ans;
while(q--)
{
cin>>x>>y>>k;
ans=qpow(s,k);
printf("%d\n",ans.m[x][y]);
}
}
return 0;
}