Description###

HH有个一成不变的习惯,喜欢饭后百步走。所谓百步走,就是散步,就是在一定的时间 内,走过一定的距离。 但

是同时HH又是个喜欢变化的人,所以他不会立刻沿着刚刚走来的路走回。 又因为HH是个喜欢变化的人,所以他每

天走过的路径都不完全一样,他想知道他究竟有多 少种散步的方法。 现在给你学校的地图(假设每条路的长度都

是一样的都是1),问长度为t,从给定地 点A走到给定地点B共有多少条符合条件的路径

Input###

第一行:五个整数N,M,t,A,B。

N表示学校里的路口的个数

M表示学校里的 路的条数

t表示HH想要散步的距离

A表示散步的出发点

B则表示散步的终点。

接下来M行

每行一组Ai,Bi,表示从路口Ai到路口Bi有一条路。

数据保证Ai != Bi,但不保证任意两个路口之间至多只有一条路相连接。

路口编号从0到N -1。

同一行内所有数据均由一个空格隔开,行首行尾没有多余空格。没有多余空行。

答案模45989。

N ≤ 20,M ≤ 60,t ≤ 2^30,0 ≤ A,B

Output###

一行,表示答案。

Sample Input###

4 5 3 0 0

0 1

0 2

0 3

2 1

3 2

Sample Output###

4


想法##

数据范围提示我用矩阵乘法。

其中每个点表示一条路而不是一个点。

然后好像没什么可说的了。。。。


代码##

  1. #include<cstdio>
  2. #include<iostream>
  3. #include<algorithm>
  4. #include<cstring>
  5. #define P 45989
  6. using namespace std;
  7. typedef long long ll;
  8. const int SZ = 140;
  9. int n,m;
  10. struct matrix{
  11. ll a[SZ][SZ];
  12. matrix() { memset(a,0,sizeof(a)); }
  13. void init() { for(int i=0;i<SZ;i++) a[i][i]=1; }
  14. matrix operator * (const matrix &b) const{
  15. matrix c;
  16. for(int i=0;i<m;i++)
  17. for(int j=0;j<m;j++)
  18. for(int k=0;k<m;k++)
  19. (c.a[i][j]+=a[i][k]*b.a[k][j])%=P;
  20. return c;
  21. }
  22. matrix operator *= (const matrix &b) { return *this=*this*b; }
  23. };
  24. matrix Pow_mod(matrix x,ll y){
  25. matrix ret; ret.init();
  26. while(y){
  27. if(y&1) ret*=x;
  28. x*=x;
  29. y>>=1;
  30. }
  31. return ret;
  32. }
  33. struct edge{
  34. int fr,to;
  35. }e[140];
  36. int A,B;
  37. ll t;
  38. int main()
  39. {
  40. int u,v;
  41. scanf("%d%d%lld%d%d",&n,&m,&t,&A,&B);
  42. for(int i=0;i<m;i++){
  43. scanf("%d%d",&u,&v);
  44. e[i*2].fr=u; e[i*2].to=v;
  45. e[i*2+1].fr=v; e[i*2+1].to=u;
  46. }
  47. m*=2;
  48. matrix a,b;
  49. for(int i=0;i<m;i++)
  50. if(e[i].fr==A) b.a[0][i]=1;
  51. for(int i=0;i<m;i++)
  52. for(int j=0;j<m;j++)
  53. if(e[i].to==e[j].fr){
  54. if(i/2==j/2) continue;
  55. a.a[i][j]=1;
  56. }
  57. a=Pow_mod(a,t-1);
  58. b=b*a;
  59. ll ans=0;
  60. for(int i=0;i<m;i++)
  61. if(e[i].to==B)
  62. (ans+=b.a[0][i])%=P;
  63. printf("%lld\n",ans);
  64. return 0;
  65. }

[bzoj1875] [洛谷P2151] [SDOI2009] HH去散步的更多相关文章

  1. 洛谷P2151 [SDOI2009] HH去散步 [矩阵加速]

    题目传送门 HH去散步 题目描述 HH有个一成不变的习惯,喜欢饭后百步走.所谓百步走,就是散步,就是在一定的时间 内,走过一定的距离. 但是同时HH又是个喜欢变化的人,所以他不会立刻沿着刚刚走来的路走 ...

  2. 洛谷 P2151 [SDOI2009]HH去散步

    题目链接 思路 如果没有不能走上一条边的限制,很显然就是dp. 设f[i][j]表示到达i点走了j步的方案数,移到k点可以表示为f[k][j+1]+=f[i][j]. 如果有限制的话,可以考虑用边表示 ...

  3. 洛谷2151[SDOI2009]HH去散步(dp+矩阵乘法优化)

    一道良好的矩阵乘法优化\(dp\)的题. 首先,一个比较\(naive\)的想法. 我们定义\(dp[i][j]\)表示已经走了\(i\)步,当前在点\(j\)的方案数. 由于题目中限制了不能立即走之 ...

  4. 「 洛谷 」P2151 [SDOI2009]HH去散步

    小兔的话 欢迎大家在评论区留言哦~ HH去散步 题目限制 内存限制:125.00MB 时间限制:1.00s 标准输入 标准输出 题目知识点 动态规划 \(dp\) 矩阵 矩阵乘法 矩阵加速 矩阵快速幂 ...

  5. P2151 [SDOI2009]HH去散步

    题目描述 HH有个一成不变的习惯,喜欢饭后百步走.所谓百步走,就是散步,就是在一定的时间 内,走过一定的距离. 但是同时HH又是个喜欢变化的人,所以他不会立刻沿着刚刚走来的路走回. 又因为HH是个喜欢 ...

  6. Luogu P2151 [SDOI2009]HH去散步 矩乘加速DP

    思路:矩乘优化DP 提交:3次(用了一个奇怪的东西导致常数过大) 题解: 如果可以走完正向边后又走反向边那就显然了,但是不能走,所以我们要将正反向边分别编号,区分正反向边. 所以这道题的矩阵是以边的编 ...

  7. AC日记——[SDOI2009]HH去散步 洛谷 P2151

    [SDOI2009]HH去散步 思路: 矩阵快速幂递推(类似弗洛伊德): 给大佬跪烂-- 代码: #include <bits/stdc++.h> using namespace std; ...

  8. bzoj1875: [SDOI2009]HH去散步

    终于A了...早上按自己以前的写法一直WA.下午换了一种写法就A了qwq #include<cstdio> #include<cstring> #include<iost ...

  9. BZOJ 1875: [SDOI2009]HH去散步( dp + 矩阵快速幂 )

    把双向边拆成2条单向边, 用边来转移...然后矩阵乘法+快速幂优化 ------------------------------------------------------------------ ...

随机推荐

  1. linux进程简单睡眠

    当一个进程睡眠, 它这样做以期望某些条件在以后会成真. 如我们之前注意到的, 任何睡 眠的进程必须在它再次醒来时检查来确保它在等待的条件真正为真. Linux 内核中睡眠的 最简单方式是一个宏定义, ...

  2. EJB实例

    两种管理机制: 无状态bean使用实例池技术管理bean 有状态bean使用激活(activation)管理bean 内存对象序列化到磁盘 磁盘反序列化到内存

  3. SVG路径无法识别问题

    SVG 路径不规范无法识别 使用 (?<=(,|-))\. 替换为0. 即可

  4. 慕课网electron写音乐播放器教程,代码跟随教程变动(十)

    添加播放状态,首先是歌曲名称和时间 在index.html中添加 <div class="container fixed-bottom bg-white pb-4"> ...

  5. codeforces 11D(状压dp)

    传送门:https://codeforces.com/problemset/problem/11/D 题意: 求n个点m条边的图里面环的个数 题解: 点的范围只有19,很容易想到是状压. dp[sta ...

  6. 学习Java第二周

    这是学习java的第二周,又这样不知不觉的结束了 上周想要学习的这一周也都做到了,可是觉得进度有些慢了,学习了: 1. 接口和抽象类: 2. 集合与数组: 3. 方法的定义: 4. 递归算法: 5.对 ...

  7. 25.python之面向对象

    一 三大编程范式 正本清源一:有人说,函数式编程就是用函数编程--->傻逼 编程范式即编程的方法论,标识一种编程风格 大家学习了基本的python语法后,大家就可以写python代码了,然后每个 ...

  8. c#链接redis用户名密码

    方法一 使用:ServiceStack.Redis 在ip:port前面加上@用来表示密码,比如password@ip:port <add key="RedisServer" ...

  9. 牛客国庆days赛 地铁

    传送门:https://ac.nowcoder.com/acm/problem/52805 我佛了,还能跑边图啊!!! 跑边图不能用vector啦啦啦啦啦 具体也不难,就直接上代码了 #include ...

  10. 【题解】P4755 Beautiful Pair(启发式合并的思路+分治=启发式分治)

    [题解]P4755 Beautiful Pair upd: 之前一个first second烦了,现在AC了 由于之前是直接抄std写的,所以没有什么心得体会,今天自己写写发现 不知道为啥\(90\) ...