您的位置:首页 > 其它

How many ways??---hdu2157(矩阵快速幂)

2016-04-12 14:35 316 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2157

题意:有一个有向图,含有n个节点,m条边,Q个询问,每个询问有 s,t,p,求 s 到 t 经过 p 个点(这 p 个点包括 t 点,不包括 s 点)的所有方案数对100求余;

我们知道floyd算法中(i, j)是可以由(i,k)和(k,j)得到;那么就是经过k这个中间节点;这样一来就是 i -- k -- j 经过两个节点(k,j)所以从 i 到 j 经过2个点的方案总数是 (i,j)= ∑(i,k)*(k,j);(枚举所有的

k )然而这个正是矩阵(A*A)相乘的结果

以此类推经过3个点,4个点...p个点所求就是A^p中的(s, t);

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#include <map>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;

#define N 50
#define MOD 1000
#define met(a, b) memset(a, b, sizeof(a))
#define INF 0x3f3f3f3f

typedef long long LL;

struct Matrix
{
int a

;
Matrix()
{
memset(a, 0, sizeof(a));///注意初始化;
}
};

int n, m;

Matrix Mul(Matrix p, Matrix q)
{
Matrix temp;///注意初始化;

for(int i=0; i<n; i++)
{
for(int j=0; j<n; j++)
{
for(int k=0; k<n; k++)
temp.a[i][j] = (temp.a[i][j] + p.a[i][k]*q.a[k][j]) % MOD;
}
}
return temp;
}

Matrix Pow(Matrix Matrix0, int k)
{
Matrix temp, Matrix1 = Matrix0;

for(int i=0; i<N; i++)
temp.a[i][i] = 1;///注意初始化;

while(k)
{
if(k%2 == 1)
temp = Mul(temp, Matrix1);
Matrix1 = Mul(Matrix1, Matrix1);
k /= 2;
}
return temp;
}

int main()
{
int u, v, k, Q;

while(scanf("%d %d", &n, &m), m+n)
{
Matrix Matrix0;

for(int i=1; i<=m; i++)
{
scanf("%d %d", &u, &v);
Matrix0.a[u][v] = 1;
}

scanf("%d", &Q);

while(Q--)
{
scanf("%d %d %d", &u, &v, &k);

Matrix answer = Pow(Matrix0, k);

printf("%d\n", answer.a[u][v]);
}
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: