矩阵经典题目八:hdu 2175 How many ways??

http://acm.hdu.edu.cn/showproblem.php?pid=2157

给定一个有向图,问从A点恰好走k步(允许重复经过边)到达B点的方案数mod p的值

把给定的图转为邻接矩阵,即A(i,j)=1当且仅当存在一条边i->j。令C=A*A,那么C(i,j)=ΣA(i,k)*A(k,j),实际上就等于从点i到点j恰好经过2条边的路径数(枚举k为中转点)。类似地,C*A的第i行第j列就表示从i到j经过3条边的路径数。同理,如果要求经过k步的路径数,我们只需要二分求出A^k即可。

#include <stdio.h>
#include <iostream>
#include <map>
#include <set>
#include <list>
#include <stack>
#include <vector>
#include <math.h>
#include <string.h>
#include <queue>
#include <string>
#include <stdlib.h>
#include <algorithm>
#define LL long long
#define _LL __int64
#define eps 1e-12
#define PI acos(-1.0)
#define C 240
#define S 20
using namespace std;

const int maxn = 25;
const int mod = 1000;

int n;
struct matrix
{
	int mat[maxn][maxn];
	void init()
	{
		memset(mat,0,sizeof(mat));
		for(int i = 0; i < maxn; i++)
			mat[i][i] = 1;
	}
}a;

matrix mul(matrix a, matrix b)
{
	matrix ans;
	memset(ans.mat,0,sizeof(ans.mat));
	for(int i = 0; i < n; i++)
	{
		for(int k = 0; k < n; k++)
		{
			if(a.mat[i][k] == 0) continue;
			for(int j = 0; j < n; j++)
			{
				ans.mat[i][j] += a.mat[i][k] * b.mat[k][j]%mod;
				ans.mat[i][j] %= mod;
			}
		}
	}
	return ans;
}

matrix pow(matrix a, int n)
{
	matrix ans;
	ans.init();
	while(n)
	{
		if(n&1)
			ans = mul(ans,a);
		a = mul(a,a);
		n >>= 1;
	}
	return ans;
}

int main()
{
	int m,T,u,v,k;
	while(~scanf("%d %d",&n,&m))
	{
		if(n == 0 && m == 0) break;
		memset(a.mat,0,sizeof(a.mat));
		while(m--)
		{
			scanf("%d %d",&u,&v);
			a.mat[u][v] = 1;
		}
		scanf("%d",&T);
		while(T--)
		{
			scanf("%d %d %d",&u,&v,&k);
			matrix ans = pow(a,k);
			printf("%d\n",ans.mat[u][v]);
		}
	}
	return 0;
}

矩阵经典题目八:hdu 2175 How many ways??

时间: 2024-11-09 01:15:25

矩阵经典题目八:hdu 2175 How many ways??的相关文章

矩阵经典题目七:Warcraft III 守望者的烦恼(矩阵加速递推)

https://www.vijos.org/p/1067 很容易推出递推式f[n] = f[n-1]+f[n-2]+......+f[n-k]. 构造矩阵的方法:构造一个k*k的矩阵,其中右上角的(k-1)*(k-1)的矩阵是单位矩阵,第k行的每个数分别对应f[n-1],f[n-2],,f[n-k]的系数.然后构造一个k*1的矩阵,它的第i行代表f[i],是经过直接递推得到的.设ans[][]是第一个矩阵的n-k次幂乘上第二个矩阵,f[n]就是ans[k][1]. 注意:用__int64 #in

矩阵经典题目四:送给圣诞夜的礼品(使用m个置换实现对序列的转变)

https://vijos.org/p/1049 给出一个序列,含n个数.然后是m个置换,求对初始序列依次进行k次置换,求最后的序列. 先看一个置换,把置换表示成矩阵的形式,然后将m个置换乘起来.那么初始序列首先执行这个置换k/m次,然后顺次执行前k%m个置换,最后乘上初始矩阵. 最后注意矩阵乘法的顺序,A*B != B*A. #include <stdio.h> #include <iostream> #include <map> #include <set&g

矩阵经典题目六:poj 3070 Fibonacci

http://poj.org/problem?id=3070 按已构造好的矩阵,那么该矩阵的n次方的右上角的数便是f[n]. #include <stdio.h> #include <iostream> #include <map> #include <set> #include <list> #include <stack> #include <vector> #include <math.h> #inclu

学习心得:《十个利用矩阵乘法解决的经典题目》from Matrix67

本文来自:http://www.matrix67.com/blog/archives/tag/poj大牛的博文学习学习 节选如下部分:矩阵乘法的两个重要性质:一,矩阵乘法不满足交换律:二,矩阵乘法满足结合律经典题目1 给定n个点,m个操作,构造O(m+n)的算法输出m个操作后各点的位置.操作有平移.缩放.翻转和旋转    这 里的操作是对所有点同时进行的.其中翻转是以坐标轴为对称轴进行翻转(两种情况),旋转则以原点为中心.如果对每个点分别进行模拟,那么m个操作总共耗时 O(mn).利用矩阵乘法可

十个利用矩阵乘法解决的经典题目

转载自    Matrix67: The Aha Moments 好像目前还没有这方面题目的总结.这几天连续看到四个问这类题目的人,今天在这里简单写一下.这里我们不介绍其它有关矩阵的知识,只介绍矩阵乘法和相关性质.    不要以为数学中的矩阵也是黑色屏幕上不断变化的绿色字符.在数学中,一个矩阵说穿了就是一个二维数组.一个n行m列的矩阵可以乘以一个m行p列的矩阵,得到的结果是一个n行p列的矩阵,其中的第i行第j列位置上的数等于前一个矩阵第i行上的m个数与后一个矩阵第j列上的m个数对应相乘后所有m个

矩阵乘法的经典题目_源自Matrix67_

嘛,都刷一遍好辣. 矩阵Am?n就是一个m行n列的数表. 考虑矩阵的乘法: C=A?B=∑aik?bkj 那么对于矩阵A的要求就是:A为m * n的矩阵 对于矩阵B的要求就是:B为n * p的矩阵 乘得的矩阵C的规模:m * p的矩阵 矩阵乘法是不满足交换律的.但它满足结合律和分配律. 经典题目1 给定n个点,m个操作,构造O(m+n)的算法输出m个操作后各点的位置.操作有平移.缩放.翻转和旋转 然后盗图 考虑实际上这个变换对应着一个类似于线性变换的东西,我们显然是可以用矩阵来搞的. 而对于翻转

[转]十个利用矩阵乘法解决的经典题目

好像目前还没有这方面题目的总结.这几天连续看到四个问这类题目的人,今天在这里简单写一下.这里我们不介绍其它有关矩阵的知识,只介绍矩阵乘法和相关性质.    不要以为数学中的矩阵也是黑色屏幕上不断变化的绿色字符.在数学中,一个矩阵说穿了就是一个二维数组.一个n行m列的矩阵可以乘以一个m行p列的矩阵,得到的结果是一个n行p列的矩阵,其中的第i行第j列位置上的数等于前一个矩阵第i行上的m个数与后一个矩阵第j列上的m个数对应相乘后所有m个乘积的和.比如,下面的算式表示一个2行2列的矩阵乘以2行3列的矩阵

矩阵十题【九】 HDU 2157 How many ways??

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2157 题目大意:给定一个有向图,问从A点恰好走k步(允许重复经过边)到达B点的方案数mod p的值 本来以为是DFS搜索,发现用矩阵也可以做!~ 好神奇. 把 给定的图转为邻接矩阵,即A(i,j)=1当且仅当存在一条边i->j.令C=A*A,那么C(i,j)=ΣA(i,k)*A(k,j),实际上就 等于从点i到点j恰好经过2条边的路径数(枚举k为中转点).类似地,C*A的第i行第j列就表示从i到j

数论基础题目八题【欧几里得】【筛法素数】【中国剩余定理】

之前看的数论的知识,现在做几道题目找找感觉..... poj 1061 传送门 题目大意,给你x,y,m,n,L.代表青蛙a的坐标x,青蛙b的坐标y,青蛙a一次跳的距离m,青蛙b一次跳的距离n,以及mod的值L,求经过多少次跳相遇.即求:(m-n)*x0=(x-y)(mod L);  模线性方程的解,不过要注意处理,因为(m-n)和(x-y)有可能是负的,如果(m-n)是负的,则直接对俩数取负数,下面就是对 ((x-y)+L)%L. 然后就能用modular_linear_equation(LL