标签:iostream 重复 ref ali 一个 mission 表示 允许 多少
任意门:http://acm.hdu.edu.cn/showproblem.php?pid=2157
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 5339 Accepted Submission(s): 2109
给一个有向图,问从A点恰好走k步(允许重复经过边)到达B点的方案数(mod 1000)
把 给定的图 D 转为邻接矩阵,即A(i,j)=1当且仅当存在一条边 i->j。
则 A的 l 次幂 Al ( l >= 1) 中元素 aij(l) 为 D 中 vi -> vj 长度为 l 的通路数。
AC code:
1 #include <cstdio> 2 #include <iostream> 3 #include <algorithm> 4 #include <cstring> 5 #include <cmath> 6 #define LL long long 7 #define Mod 1000 8 using namespace std; 9 const int MAXN = 101; 10 int N, M, T; 11 12 struct mat 13 { 14 int m[MAXN][MAXN]; 15 }base, tmp, ans; 16 17 mat muti(mat a, mat b) 18 { 19 mat res; 20 memset(res.m, 0, sizeof(res.m)); 21 22 for(int i = 0; i < N; i++) 23 for(int j = 0; j < N; j++) 24 { 25 if(a.m[i][j]){ 26 for(int k = 0; k < N; k++) 27 res.m[i][k] = (res.m[i][k] + a.m[i][j] * b.m[j][k])%Mod; 28 } 29 } 30 return res; 31 } 32 33 mat qpow(mat a, int n) 34 { 35 mat res; 36 memset(res.m, 0, sizeof(res.m)); 37 for(int i = 0; i < N; i++) res.m[i][i] = 1; 38 while(n){ 39 if(n&1) res = muti(res, a); 40 n>>=1; 41 a = muti(a, a); 42 } 43 return res; 44 } 45 46 int main() 47 { 48 int a, b, k; 49 while(~scanf("%d%d", &N, &M) && (N+M)){ 50 memset(base.m, 0, sizeof(base.m)); 51 for(int i = 1; i <= M; i++){ 52 scanf("%d%d", &a, &b); 53 base.m[a][b] = 1; 54 } 55 56 scanf("%d", &T); 57 while(T--){ 58 scanf("%d%d%d", &a, &b, &k); 59 ans = qpow(base, k); 60 printf("%d\n", ans.m[a][b]); 61 } 62 } 63 return 0; 64 }
HDU 2157 How many ways?? 【矩阵经典8】
标签:iostream 重复 ref ali 一个 mission 表示 允许 多少
原文地址:https://www.cnblogs.com/ymzjj/p/9949961.html