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

---------------------------------------------------------------------------------------------

#include<cstdio>
#include<cstring>
#include<algorithm>
 
using namespace std;
 
const int MOD = 45989;
const int maxn = 29;
const int maxm = 129;
 
int N, M, T, A, B;
int U[maxm], V[maxm], Id[maxm], f[maxm];
 
struct matrix {
int a[maxm][maxm];
matrix() {
memset(a, 0, sizeof a);
}
matrix operator * (const matrix &o) const {
matrix ret;
for(int i = 0; i < M; i++)
for(int k = 0; k < M; k++)
for(int j = 0; j < M; j++)
(ret.a[i][j] += a[i][k] * o.a[k][j]) %= MOD;
return ret;
}
matrix operator = (const matrix &o) {
memcpy(a, o.a, sizeof a);
return *this;
}
void Unit() {
for(int i = 0; i < M; i++)
a[i][i] = 1;
}
} mat, base;
 
void init() {
scanf("%d%d%d%d%d", &N, &M, &T, &A, &B);
for(int i = 0; i < M; i++) {
scanf("%d%d", U + i, V + i);
U[i + M] = V[i];
V[i + M] = U[i];
Id[i] = Id[i + M] = i;
}
}
 
int main() {
init();
M <<= 1;
for(int i = 0; i < M; i++)
for(int j = 0; j < M; j++)
if(Id[i] != Id[j] && V[i] == U[j]) base.a[j][i] = 1;
mat.Unit();
for(T--; T; T >>= 1, base = base * base)
if(T & 1) mat = mat * base;
memset(f, 0, sizeof f);
for(int i = 0; i < M; i++)
if(U[i] == A) f[i] = 1;
int ans = 0;
for(int i = 0; i < M; i++) if(V[i] == B)
for(int j = 0; j < M; j++)
if((ans += mat.a[i][j] * f[j]) >= MOD) ans -= MOD;
printf("%d\n", ans);
return 0;

---------------------------------------------------------------------------------------------

1875: [SDOI2009]HH去散步

Time Limit: 20 Sec  Memory Limit: 64 MB
Submit: 1027  Solved: 469
[Submit][Status][Discuss]

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。

Output

一行,表示答案。

Sample Input

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

Sample Output

4

HINT

对于30%的数据,N ≤ 4,M ≤ 10,t ≤ 10。
对于100%的数据,N ≤ 20,M ≤ 60,t ≤ 230,0 ≤ A,B

Source

BZOJ 1875: [SDOI2009]HH去散步( dp + 矩阵快速幂 )的更多相关文章

  1. BZOJ.1875.[SDOI2009]HH去散步(DP 矩阵乘法)

    题目链接 比较容易想到用f[i][j]表示走了i步后到达j点的方案数,但是题目要求不能走上一条走过的边 如果这样表示是不好转移的 可以考虑边,f[i][j]表示走了i步后到达第j条边的方案数,那么有 ...

  2. [bzoj1875][SDOI2009] HH去散步 [dp+矩阵快速幂]

    题面 传送门 正文 其实就是让你求有多少条长度为t的路径,但是有一个特殊条件:不能走过一条边以后又立刻反着走一次(如果两次经过同意条边中间隔了别的边是可以的) 如果没有这个特殊条件,我们很容易想到dp ...

  3. BZOJ 1875: [SDOI2009]HH去散步(矩阵乘法)

    首先,题意就把我们引向了矩阵乘法,注意边长m<=60,那么就按边建图,变成一个120个点的图,然后乱搞就行了。 PS:WA了N久改了3次终于A了QAQ CODE: #include<cst ...

  4. BZOJ 1875 [SDOI2009]HH去散步 ——动态规划 矩阵乘法

    发现t非常大,所以大概就是快速幂一类的问题了, 然后根据k^3logn算了算,发现k大约是边数的时候复杂度比较合适. 发现比较麻烦的就是前驱的记录,所以直接把边看做点,不能走反向边,但是可以走重边,然 ...

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

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

  6. 【SDOI2009】HH去散步(矩阵快速幂)

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

  7. bzoj 1875 [SDOI2009]HH去散步(矩乘)

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

  8. bzoj 1875: [SDOI2009]HH去散步

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

  9. 1875. [SDOI2009]HH去散步【矩阵乘法】

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

随机推荐

  1. NET CORE 应用程序启动

    原文:Application Startup作者:Steve Smith翻译:刘怡(AlexLEWIS)校对:谢炀(kiler398).许登洋(Seay) ASP.NET Core 为你的应用程序提供 ...

  2. PADS LAYOUT到底怎么走线

    PADS LAYOUT走线,是不是转角要自己手动慢慢转角啊?不能像PROTEL中那样自动转角吗 自己手动转角老是转不好,出现许多线头,对不齐,是不是我操作有误啊 走线的过程中,可以试试这个,切换端点. ...

  3. CF#52 C Circular RMQ (线段树区间更新)

    Description You are given circular array a0, a1, ..., an - 1. There are two types of operations with ...

  4. ubuntu 14.04设备flash媒体播放器

    今天是2014年4一个月19日本,就在两天前公布 ubuntu 14.04版本号, 以今天的优势是星期六,西安小雨,所以折腾linux. 我是个有点linux基础的小白.说是有些基础是由于以前在上大学 ...

  5. PHP中递归函数的一个常见逻辑问题

    首先.我们得知道递归函数是什么东西.通俗来讲也就是自己调用自己本身的函数. 如今须要设计一段代码.解决1到10叠加的问题. 代码A: <?php //递归函数 $num=10; function ...

  6. if...else if...else

    using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace prog ...

  7. Cookie获取、设置值

    设置: HttpCookie cookie = new HttpCookie("cookieName"); cookie.Value = "name1" Htt ...

  8. 使用命令行将Excel数据表导入Mysql中的方法小结

    从Excel数据表导入MySQL,已经做过好几次了,但每次都会碰到各种问题:invalid utf8 character string, data too long, ...,浪费了不少时间 为了提高 ...

  9. Visual Studio的ASP.NET修改默认打开浏览器

    1.新建web空应用程序,输入项目名称. 2.右击项目名称,添加“新建项”—一般处理程序 3.右击新建一个HTML文件,任意命名. 4.右击新建的Html文件,选择“浏览方式” 5.选择后弹出浏览器选 ...

  10. 【转】sqlserver数据库之间的表的复制

    以下以数据库t1和test为例.  1.复制表结构及资料 select * into 数据库名.dbo.表名 from 源表(全部数据)     如:select * into t1.dbo.YS1 ...