How many ways?

?

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 2046    Accepted Submission(s): 758

Problem Description
春天到了, HDU校园里开满了花, 姹紫嫣红, 很漂亮. 葱头是个爱花的人, 看着校花校草竞相开放, 漫步校园, 心情也变得舒畅. 为了多看看这迷人的校园, 葱头决定, 每次上课都走不同的路线去教室, 可是因为时间问题, 每次仅仅能经过k个地方, 例如说, 这次葱头决定经过2个地方, 那他能够先去问鼎广场看看喷泉, 再去教室, 也能够先到体育场跑几圈, 再到教室. 他很想知道, 从A 点恰好经过k个点到达B点的方案数, 当然这个数有可能很大, 所以你仅仅要输出它模上1000的余数就能够了. 你能帮帮他么?

?
你可决定了葱头一天能看多少校花哦

 
Input
输入数据有多组, 每组的第一行是2个整数 n, m(0 < n <= 20, m <= 100) 表示校园内共同拥有n个点, 为了方便起见, 点从0到n-1编号,接着有m行, 每行有两个整数 s, t (0<=s,t<n) 表示从s点能到t点, 注意图是有向的.接着的一行是两个整数T,表示有T组询问(1<=T<=100),

接下来的T行, 每行有三个整数 A, B, k, 表示问你从A 点到 B点恰好经过k个点的方案数 (k < 20), 能够走反复边。假设不存在这种走法, 则输出0

当n, m都为0的时候输入结束
 
Output
计算每次询问的方案数, 因为走法非常多, 输出其对1000取模的结果
 
Sample Input
4 4
0 1
0 2
1 3
2 3
2
0 3 2
0 3 3
3 6
0 1
1 0
0 2
2 0
1 2
2 1
2
1 2 1
0 1 3
0 0
 
Sample Output
2
0
1
3
 
Author
小黑
 
Source
 
Recommend
 

中文题~

解题思路:经典矩阵算法。把给定的图转为邻接矩阵,即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就可以。

第一道矩阵高速幂。写的比較乱。并且这样的写法时间复杂度较高,没有优化。只是比較easy看懂。

矩阵高速幂预备知识:

①矩阵相乘规则:

矩阵与矩阵相乘 第一个矩阵的列数必须等于第二个矩阵的行数 假如第一个是m*n的矩阵 第二个是n*p的矩阵 则结果就是m*p的矩阵 且得出来的矩阵中元素具有下面特点:

第一行第一列元素为第一个矩阵的第一行的每一个元素和第二个矩阵的第一列的每一个元素乘积的和 以此类推 第i行第j列的元素就是第一个矩阵的第i行的每一个元素与第二个矩阵第j列的每一个元素的乘积的和。

②单位矩阵:

n*n的矩阵  mat ( i , i )=1;  不论什么一个矩阵乘以单位矩阵就是它本身 n*单位矩阵=n, 能够把单位矩阵等价为整数1.

③高速幂:

这里矩阵高速幂等价于整数的高速幂,这里不再具体讲述

上代码:

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <algorithm> int s[25][25];
int b[25][25];
int n,m;
int a[25][25]; void Mat(int x[25][25],int y[25][25],int modn)
{
int c[25][25];
memset(c,0,sizeof(c)); //记得初始化
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
for(int k=0;k<n;k++)
c[i][j]=(c[i][j]+x[i][k]*y[k][j]%modn)%modn;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
x[i][j]=c[i][j];
} int Matrix(int begin,int end,int k)
{
for(int i=0;i<n;i++){ //初始化一个单位矩阵
for(int j=0;j<n;j++){
a[i][j]=(i==j);
}
}
for(int i=0;i<n;i++){ //记得用s保存再赋给b,不然b值变了之后结果就不正确了
for(int j=0;j<n;j++){
b[i][j]=s[i][j];
}
}
while(k){
if(k&1)Mat(a,b,1000);
Mat(b,b,1000);
k>>=1;
}
return a[begin][end];
} int main()
{
while(scanf("%d%d",&n,&m),n!=0||m!=0){
int S,G;
memset(b,0,sizeof(b));
memset(s,0,sizeof(s));
for(int i=0;i<m;i++){
scanf("%d%d",&S,&G);
s[S][G]=1;
}
int T;
scanf("%d",&T);
int B,E,k;
while(T--){
scanf("%d%d%d",&B,&E,&k);
int res=Matrix(B,E,k);
printf("%d\n",res);
}
}
return 0;
}

HDOJ How many ways?? 2157【矩阵高速幂】的更多相关文章

  1. HDOJ 4686 Arc of Dream 矩阵高速幂

    矩阵高速幂: 依据关系够建矩阵 , 高速幂解决. Arc of Dream Time Limit: 2000/2000 MS (Java/Others)    Memory Limit: 65535/ ...

  2. HDOJ 5411 CRB and Puzzle 矩阵高速幂

    直接构造矩阵,最上面一行加一排1.高速幂计算矩阵的m次方,统计第一行的和 CRB and Puzzle Time Limit: 2000/1000 MS (Java/Others)    Memory ...

  3. HDOJ 4549 M斐波那契数列 费马小定理+矩阵高速幂

    MF( i ) = a ^ fib( i-1 ) * b ^ fib ( i )   ( i>=3) mod 1000000007 是质数 , 依据费马小定理  a^phi( p ) = 1 ( ...

  4. UVA 11551 - Experienced Endeavour(矩阵高速幂)

    UVA 11551 - Experienced Endeavour 题目链接 题意:给定一列数,每一个数相应一个变换.变换为原先数列一些位置相加起来的和,问r次变换后的序列是多少 思路:矩阵高速幂,要 ...

  5. UVA10518 - How Many Calls?(矩阵高速幂)

    UVA10518 - How Many Calls?(矩阵高速幂) 题目链接 题目大意:给你fibonacci数列怎么求的.然后问你求f(n) = f(n - 1) + f(n - 2)须要多少次调用 ...

  6. HDU2842-Chinese Rings(递推+矩阵高速幂)

    pid=2842">题目链接 题意:求出最少步骤解出九连环. 取出第k个的条件是,k-2个已被取出,k-1个仍在支架上. 思路:想必九连环都玩过吧,事实上最少步骤就是从最后一个环開始. ...

  7. HDU2276 - Kiki &amp; Little Kiki 2(矩阵高速幂)

    pid=2276">题目链接 题意:有n盏灯.编号从1到n.他们绕成一圈,也就是说.1号灯的左边是n号灯.假设在第t秒的时候,某盏灯左边的灯是亮着的,那么就在第t+1秒的时候改变这盏灯 ...

  8. uva 10655 - Contemplation! Algebra(矩阵高速幂)

    题目连接:uva 10655 - Contemplation! Algebra 题目大意:输入非负整数,p.q,n,求an+bn的值,当中a和b满足a+b=p,ab=q,注意a和b不一定是实数. 解题 ...

  9. hdu 3221 Brute-force Algorithm(高速幂取模,矩阵高速幂求fib)

    http://acm.hdu.edu.cn/showproblem.php?pid=3221 一晚上搞出来这么一道题..Mark. 给出这么一个程序.问funny函数调用了多少次. 我们定义数组为所求 ...

随机推荐

  1. LeetCode答案(python)

    1. 两数之和 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标. 你可以假设每种输入只会对应一个答案.但是,你不能重复利用这 ...

  2. CentOS 7.0:搭建SVN服务器

    1. 通过 yum install subversion来安装 2. 提示已经安装.查看svn版本 第二步: 创建svn版本库 第三步: 配置svn信息 2. 配置权限配置文件authz 3. 配置用 ...

  3. python基础学习笔记——time模块

    time模块 time翻译过来就是时间,有我们其实在之前编程的时候有用到过. #常用方法 1.time.sleep(secs) (线程)推迟指定的时间运行.单位为秒. 2.time.time() 获取 ...

  4. C# 导出Excel的示例

    Excel知识点.  一.添加引用和命名空间 添加Microsoft.Office.Interop.Excel引用,它的默认路径是C:\Program Files\Microsoft Visual S ...

  5. Java-转换原始类型为一个字符串

    package com.tj; public class MyClass implements Cloneable { public static void main(String[] args) { ...

  6. mysql replication常见错误整理

    这篇文章旨在记录MySQL Replication的常见错误,包括自己工作中遇到的与网友在工作中遇到的,方面自己及别人以后进行查找.每个案例都是通过Last_IO_Errno/Last_IO_Erro ...

  7. bootshiro---开源的后台管理框架--基于springboot2+ shiro+jwt的真正rest api资源无状态认证权限管理框架,开发人员无需关注权限问题,后端开发完api,前端页面配置即可

    https://gitee.com/tomsun28/bootshiro

  8. 虚拟机安装centos6.5

    最近想搞一下代码覆盖率的jacoco,需要在linux环境下部署一套jenkins.故需要装一个centos的虚拟机. 一.安装虚拟机. 下载后安装一个虚拟机,我选择的是VMware虚拟机 二.安装c ...

  9. 【Luogu】P1119灾后重建(Floyd)

    题目链接 见题解: feilongz. 这里只放代码. #include<cstdio> #include<cstring> #include<cstdlib> # ...

  10. tarkjan求无向图割点模板

    #include<bits/stdc++.h> using namespace std; typedef long long ll; int n,m; ; ; struct node { ...