题目链接:BZOJ - 1875

题目分析:

  这道题如果去掉“不会立刻沿着刚刚走来的路走回”的限制,直接用邻接矩阵跑矩阵乘法就可以了。然而现在加了这个限制,建图的方式就要做一些改变。如果我们把每一条边看做点建矩阵,那么每次从一条边出发都只会到其他的边,不能仍然在这条边上“停留”,所以这就可以满足题目的限制。将每条边拆成两条单向边,比如一条编号为 4,一条编号为 5。那么 4^1=5, 5^1=4。这样只要不从第 i 条边走到 i 或 i^1 就可以了。初始的矩阵中以 A 为起点的边到达的方案数为 1 ,其余为 0。最后将终点为 B 的边的方案数累加即为答案。、

  这种将边与点灵活转化的思想十分巧妙,应注意。

代码如下:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm> using namespace std; const int MaxN = 20 + 5, MaxM = 120 + 5, Mod = 45989; int n, m, t, A, B, TopA, TopB, Index, RT, Ans, a, b;
int EA[MaxM], EB[MaxM]; struct Edge
{
int u, v;
Edge() {}
Edge(int a, int b) {
u = a; v = b;
}
} E[MaxM]; struct Matrix
{
int x, y, Num[MaxM][MaxM];
void SetXY(int xx, int yy) {
x = xx; y = yy;
}
void Clear(int nn) {
for (int i = 0; i < x; ++i) {
for (int j = 0; j < y; ++j) {
Num[i][j] = nn;
}
}
}
} M0, MZ; Matrix Mul(Matrix A, Matrix B) {
Matrix ret;
ret.SetXY(A.x, B.y);
ret.Clear(0);
for (int i = 0; i < ret.x; ++i) {
for (int j = 0; j < ret.y; ++j) {
for (int k = 0; k < A.y; ++k) {
ret.Num[i][j] += A.Num[i][k] * B.Num[k][j];
ret.Num[i][j] %= Mod;
}
}
}
return ret;
} Matrix Pow(Matrix A, int b) {
Matrix ret, f;
f = A;
ret.SetXY(f.x, f.y);
for (int i = 0; i <= ret.x; ++i) ret.Num[i][i] = 1;
while (b) {
if (b & 1) ret = Mul(ret, f);
b >>= 1;
f = Mul(f, f);
}
return ret;
} int main()
{
scanf("%d%d%d%d%d", &n, &m, &t, &A, &B);
Index = -1;
for (int i = 1; i <= m; ++i) {
scanf("%d%d", &a, &b);
E[++Index] = Edge(a, b);
E[++Index] = Edge(b, a);
}
MZ.SetXY(m * 2, m * 2);
MZ.Clear(0);
TopA = TopB = 0;
for (int i = 0; i <= Index; ++i) {
if (E[i].u == A) EA[++TopA] = i;
if (E[i].v == B) EB[++TopB] = i;
for (int j = 0; j <= Index; ++j) {
if (i != j && i != (j ^ 1) && E[i].v == E[j].u)
MZ.Num[i][j] = 1;
}
}
M0.SetXY(1, m * 2);
M0.Clear(0);
for (int i = 1; i <= TopA; ++i) M0.Num[0][EA[i]] = 1;
MZ = Pow(MZ, t - 1);
M0 = Mul(M0, MZ);
Ans = 0;
for (int i = 1; i <= TopB; ++i) {
Ans += M0.Num[0][EB[i]];
Ans %= Mod;
}
printf("%d\n", Ans);
return 0;
}

  

[BZOJ 1875] [SDOI 2009] HH去散步【矩阵乘法】的更多相关文章

  1. sdoi 2009 HH去散步 矩阵乘

    如果没有题里的"不会立刻沿着刚刚走来的路走回"限制,那么直接矩乘计算k步的方案数 但加了这个限制,就不能以点来矩乘了,考虑边数<=60,如果以边建邻接矩阵呢?? 先拆边,再把 ...

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

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

  3. 【47.40%】【BZOJ 1875】[SDOI2009]HH去散步

    Time Limit: 20 Sec  Memory Limit: 64 MB Submit: 1363  Solved: 646 [Submit][Status][Discuss] Descript ...

  4. 【bzoj1875】[SDOI2009]HH去散步 矩阵乘法

    题目描述 一张N个点M条边的无向图,从A走到B,要求:每一次不能立刻沿着上一次的边的反方向返回.求方案数. 输入 第一行:五个整数N,M,t,A,B. N表示学校里的路口的个数 M表示学校里的路的条数 ...

  5. [SDOI 2009]HH去散步

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

  6. [SDOI2009] HH去散步 (矩阵乘法)

    link $solution:$ 将边化为点后重新建矩阵,跑$T-1$幂即可(因为跑的是新边). 最后直接找与$x,y$所相连的边即可. #include<iostream> #inclu ...

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

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

  8. bzoj1875 [SDOI2009]HH去散步 矩阵快速幂

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=1875 题解 如果没有这个"不能立刻沿着刚刚走来的路走回",那么这个题就是一 ...

  9. 【BZOJ】1875: [SDOI2009]HH去散步 矩阵快速幂

    [题意]给定n个点m边的无向图,求A到B恰好经过t条边的路径数,路径须满足每条边都和前一条边不同.n<=20,m<=60,t<=2^30. [算法]矩阵快速幂 [题解]将图的邻接矩阵 ...

随机推荐

  1. android中选择控件与选择界面自然过度效果的实现--一种新的交互设计

    转载请标明出处: http://blog.csdn.net/jianghejie123/article/details/40648931 在安卓中经常遇到须要选择一个东西的功能,比方选择日期.选择文件 ...

  2. Fix java version mismatch in windows---stackoverflow

    Question: I have the 64bit version of the jdk installed on windows 7. I installed the 32 bit version ...

  3. 根据引用jar包路径查找原JAR包

    网站:http://www.findjar.com/. 就是这个网站,经常在网上看到一些好的源码,什么都说了,就是没有说明需要引入那个包,这个包需要从什么地方下载,有些时候在网上搜索还不一定搜索得到, ...

  4. Java基础知识强化之集合框架笔记18:List集合特有的ListIterator迭代器

    1. ListIterator(列表迭代器): ListIterator listIterator():List集合特有的迭代器 2. 代码示例: package cn.itcast_04; impo ...

  5. [iOS开发] 使用第三方字体不生效

    iOS中使用第三方字体并不复杂,通常只需要如下三个步骤: 1. 将第三方字体文件添加到工程(Project)中: 2. 在info.plist中添加一个新的键"Fonts provided ...

  6. asp.net下载文件的几种方法

    最近做东西遇到了下载相关的问题.在这里总结一下自己处理的方法. 1.以字节流的形式向页面输出数据以下载Excel为例子. string path=Server.MapPath("文件路径&q ...

  7. C# 内存管理优化畅想----前言

    C#语法简洁.优雅,类库丰富,是我最喜爱的计算机语言,没有“之一”.但是,经过深入学习后发现,C#的内存管理,也就是通常所说的垃圾回收(GC)机制,虽然跟其他支持GC的语言相比,已经很优秀了,但与手动 ...

  8. asp.net对word文档进行修改 对于使用word文档做模板编辑比较适用

    最近做项目,需要多word文档进行编辑并导出一个新的word,在最初的word编辑中留下特定的字符串用来替换,然后在本地生成一个新的word文档,并且不修改服务器中的word文档,这样才能保证服务器中 ...

  9. C语言中,如何通过socket得到对端IP地址

    struct sockaddr_in clientaddr1; memset(&clientaddr1, 0x00, sizeof(clientaddr1)); socklen_t nl=si ...

  10. 最简单的基于FFmpeg的移动端例子:IOS 推流器

    转至:http://blog.csdn.net/leixiaohua1020/article/details/47072519   ================================== ...