题目描述

HH有个一成不变的习惯,喜欢饭后百步走。所谓百步走,就是散步,就是在一定的时间 内,走过一定的距离。 但是同时HH又是个喜欢变化的人,所以他不会立刻沿着刚刚走来的路走回。 又因为HH是个喜欢变化的人,所以他每天走过的路径都不完全一样,他想知道他究竟有多 少种散步的方法。 现在给你学校的地图(假设每条路的长度都是一样的都是1),问长度为t,从给定地 点A走到给定地点B共有多少条符合条件的路径

输入

第一行:五个整数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

输出

一行,表示答案。

样例输入

4 5 3 0 0
0 1
0 2
0 3
2 1
3 2

样例输出

4

题解
    考试的时候想得比较粗略,一开始当然是暴力深搜,也知道这种方案数还取模的题不可能深搜出正解,但还是先打了一通,没费什么力气就出了样例。之后开始想正解,感觉或许应该把环收缩一下,但是环环相扣环环重叠不知道应该怎么处理,最后还是把深搜交上去了。
正解是矩阵优化dp(但总感觉它其实说不上是dp),比如矩阵G[i,j]的k次方中的g(a,b)可以表示从a点到b点经过k条边的方案数,本题因为对于边有特殊的要求(不立刻反向)所以把边放进矩阵,G[i,j]为1表示从i到j有一条边,这里的边是分方向的,双向建边就会有2*m条。tot矩阵(其实只有一行)表示从起点有哪些边出来。tot乘上G[i,j]的k-1次方(注意顺序,矩阵乘法不满足交换律),把得到的一行结果矩阵中有边到终点的位加和,得到的结果即为答案。
刚开始觉得矩阵非常抽象,虽然自己在课下学过很多数学书上的理论知识但还是不会用,不过这道题让我明白矩阵也是有明确含义的(加速矩阵除外),本质上还是要理解算法每一步的目的。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n,m,t,a,b,temp;
const int md=;
int dis[][]={},tot[][]={},ans[][]={};
inline int r()
{
int jg=,jk=;
jk=getchar()-'';
if(jk>=&&jk<=) jg+=jk;
jk=getchar()-'';
while(jk>=&&jk<=)
{
jg*=;
jg+=jk;
jk=getchar()-'';
}
return jg;
}
int h[],e;
struct B
{
int u,v,ne;
}bi[];
void add(int x,int y)
{
bi[e].u=x;
bi[e].v=y;
bi[e].ne=h[x];
h[x]=e++;
}
int jg[][];
void jc(int cs1[][],int cs2[][])
{
memset(jg,,sizeof(jg));
for(int i=;i<temp;i++)
for(int j=;j<temp;j++)
for(int k=;k<temp;k++)
jg[i][j]+=(cs1[i][k]*cs2[k][j])%md;
for(int i=;i<temp;i++)
for(int j=;j<temp;j++)
cs1[i][j]=jg[i][j]%md;
}
void init()
{
n=r();
m=r();
t=r();
a=r();
b=r();
temp=*m;
memset(h,-,sizeof(h));
int a1,a2;
for(int i=;i<m;i++)
{
a1=r();
a2=r();
add(a1,a2);
add(a2,a1);
}
for(int i=;i<n;i++)
for(int j=h[i];j!=-;j=bi[j].ne)
for(int k=h[bi[j].v];k!=-;k=bi[k].ne)
{
if(((k&)&&k==j+)||((j&)&&j==k+))
continue;
dis[j][k]=;
}
for(int i=h[a];i!=-;i=bi[i].ne)
tot[][i]=;
}
int main()
{
init();
for(int i=;i<temp;i++)
ans[i][i]=;
t--;
while(t)
{
if(t&) jc(ans,dis);
t>>=;
jc(dis,dis);
}
jc(tot,ans);
int res=;
for(int i=h[b];i!=-;i=bi[i].ne)
{
if(i&)
res+=tot[][i-];
else
res+=tot[][i+];
}
printf("%d",res%md);
return ;
}

 

HH去散步[SDOI2009]的更多相关文章

  1. bzoj1875: [SDOI2009]HH去散步

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

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

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

  3. BZOJ_1875_[SDOI2009]HH去散步_矩阵乘法

    BZOJ_1875_[SDOI2009]HH去散步_矩阵乘法 Description HH有个一成不变的习惯,喜欢饭后百步走.所谓百步走,就是散步,就是在一定的时间 内,走过一定的距离. 但 是同时H ...

  4. bzoj 1875: [SDOI2009]HH去散步 -- 矩阵乘法

    1875: [SDOI2009]HH去散步 Time Limit: 20 Sec  Memory Limit: 64 MB Description HH有个一成不变的习惯,喜欢饭后百步走.所谓百步走, ...

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

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

  6. 【bzoj1875】【SDOI2009】【HH去散步】

    1875: [SDOI2009]HH去散步 Time Limit: 20 Sec Memory Limit: 64 MB Submit: 932 Solved: 424 [Submit][Status ...

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

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

  8. BZOJ 1875 【SDOI2009】 HH去散步

    题目链接:HH去散步 如果不考虑不能走上一次走的边的话,这道题就是一个矩乘的裸题. 现在有了这个条件其实也很好做.我们平常的矩阵都是按点建的,\(A_{i,j}\)表示从第\(i\)个点走到第\(j\ ...

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

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

随机推荐

  1. 拉勾网招聘数据分析(Echarts, SQL, java)

    这次的数据分析与决策课程,我做的是通过爬取拉勾网上的招聘信息,并用爬取到的数据整体分析互联网行业数据,项目做得差不多了,先总结下吧,后边有时间了再完善. 主要工具:  Echarts, SQL, ja ...

  2. 一起学习c++11——c++11中的新增的容器

    c++11新增的容器1:array array最早是在boost中出现:http://www.boost.org/doc/libs/1_61_0/doc/html/array.html 当时的初衷是希 ...

  3. 很好的复习资料: SQL语句到底怎么写 ?

    本文用到的数据库如下: CREATE DATABASE exam; /*创建部门表*/ CREATE TABLE dept( deptno INT PRIMARY KEY, dname VARCHAR ...

  4. [leetcode-526-Beautiful Arrangement]

    Suppose you have N integers from 1 to N. We define a beautiful arrangement as an array that is const ...

  5. 如何简单的实现新手引导之UGUI篇

    一个完整的游戏项目肯定是要做新手引导的,而引导做的好坏可能会影响玩家的留存.那么怎么简单的实现个简有效的引导呢!先不说废话,先看看效果,这是一个基于UGUI做的一个简单的引导! 怎么样,看着是那么回事 ...

  6. 最近学习java时的记录

    1.java 的变量一共分为三种,类变量,局部变量,成员变量 类变量就是 加static修饰符的变量 2.java 的修饰符可分为两大类,一 可访问修饰符 protected private publ ...

  7. 不用EF框架,完成完美实体映射,且便于维护!(AutoMapper,petapoco)

    最近,需要搭建一个新项目,在需求分析时确定数据库中需要创建多个存储过程.所以如果还是用原来EF框架生成ADO.net实体模型的话,不利于修改. 主要是解决以下两个问题: 1.比如前端需要一个值,如果存 ...

  8. Linux下安装openvpn

    工作上常常要通过vpn访问内网环境,最近一直在linux上搞东西,为了方便起见在linux上也安装了openvpn. 本次安装的openvpn不是把它当做服务端,而仅仅是以客户端来使用,所以没有那些服 ...

  9. 集成 ssh第一阶段

    1.添加spring支持,包含spring-hibernate和spring-struts2.添加struts支持,包含struts-spring3.添加hibernate支持,在spring配置文件 ...

  10. C#字典转换成where条件

    where 1=1 and Dictionary[key1]=Dictionary[value1] and Dictionary[key2]=Dictionary[value3].... /// &l ...