题目链接

比较容易想到用f[i][j]表示走了i步后到达j点的方案数,但是题目要求不能走上一条走过的边

如果这样表示是不好转移的

可以考虑边,f[i][j]表示走了i步后到达第j条边的方案数,那么有 f[i][j] = ∑f[i-1][k] (边k能直接到达边j)

只要不走反向边,就保证了不会走上一条边了

步数很大,而这个方程显然是可以通过矩阵快速幂加速转移的

求初始边矩阵的t-1次方幂t',然后用系数矩阵(与src相连的边)乘以t',即为走了t条边后的方案数

(这个系数矩阵是为了只保留矩阵中起点是src的路径)

最终答案为所有与des相连的边的dp值

一条边肯定要拆成两条有向边

注意异或运算级比!=还低。。

O((2m)^3logt)=5e7 得卡卡常

为什么自带大常数= =有人帮忙看下吗。。

//1368kb	2900ms
#include <cstdio>
#include <cctype>
#define gc() getchar()
#define mod 45989//真的略快
const int N=150;//,mod=45989; int n,m,K,src,des,Enum,H[70],nxt[N],to[N];
struct Matrix
{
int A[N][N];
// void Clear() {memset(A,0,sizeof A);}
Matrix operator *(const Matrix &a)const
{
Matrix res;
for(int i=1; i<=m; ++i)
for(int j=1; j<=m; ++j)
{
res.A[i][j]=0;
for(int k=1; k<=m; ++k)
(res.A[i][j]+=A[i][k]*a.A[k][j])%=mod;
}
return res;
// for(int i=1; i<=m; ++i)
// for(int k=1; k<=m; ++k)
// if(A[i][k])//优化技巧 先枚举k 于是可以判是否为0 -> 于是更慢了-- 应该是洛谷评测的问题吧。。
// for(int j=1; j<=m; ++j)
// res.A[i][j]+=A[i][k]*a.A[k][j]%mod,
// res.A[i][j]>=mod ? res.A[i][j]-=mod : 0;
}
}S,tmp; inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
inline void AddEdge(int u,int v)
{
to[++Enum]=v, nxt[Enum]=H[u], H[u]=Enum;
to[++Enum]=u, nxt[Enum]=H[v], H[v]=Enum;
}
Matrix FP(Matrix x,int k)
{
Matrix t=x; --k;
for(; k; k>>=1,x=x*x)
if(k&1) t=t*x;
return t;
} int main()
{
Enum=1;
n=read(),m=read(),K=read(),src=read(),des=read();
for(int u,v,i=1; i<=m; ++i) u=read(),v=read(),AddEdge(u,v);
m=Enum;
for(int i=H[src]; i; i=nxt[i]) S.A[1][i]=1;//拿1做起点 感觉好玄学啊。。
for(int i=2; i<=m; ++i)
for(int j=H[to[i]]; j; j=nxt[j])//与边i直接相邻的边即边的端点所连的边
if(i!=(j^1)) tmp.A[i][j]=1;//++tmp.A[i][j];//这个是不需要+的,因为已经把每条边都拆了
// if(i^j^1) tmp.A[i][j]=1;
tmp=FP(tmp,K-1);
S=S*tmp;
int res=0;
for(int i=H[des]; i; i=nxt[i]) res+=S.A[1][i^1];//起点到 能到终点的边
printf("%d",res%mod); return 0;
}

另外如果没有不走前一条边的限制是不是可以倍增Floyd

考试的时候强行看漏句子 然后15min写完以为A了==

#include <cstdio>
#include <cctype>
#include <cstring>
#define gc() getchar()
const int N=30,mod=45989; int n,m,K,src,des,f[N][N],tmp[N][N],ans[N][N]; inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
void Mult(int a[N][N],int b[N][N])
{
memset(tmp,0,sizeof tmp);
for(int k=0; k<n; ++k)
for(int i=0; i<n; ++i)
for(int j=0; j<n; ++j)
tmp[i][j]+= a[i][k]*b[k][j]%mod,
tmp[i][j]>=mod ? tmp[i][j]-=mod : 0;
}
//void Print(int a[N][N])
//{
// puts("Debug");
// for(int i=0; i<n; ++i,putchar('\n'))
// for(int j=0; j<n; ++j) printf("%d ",a[i][j]);
//} int main()
{
n=read(),m=read(),K=read()-1,src=read(),des=read();
for(int u,v,i=1; i<=m; ++i)
u=read(),v=read(),++f[u][v],++f[v][u];
for(int i=0; i<n; ++i)
for(int j=0; j<n; ++j) ans[i][j]=(f[i][j]%=mod);
while(K)
{
if(K&1) Mult(ans,f), memcpy(ans,tmp,sizeof tmp);
K>>=1, Mult(f,f), memcpy(f,tmp,sizeof tmp);
// printf("now K:%d\n",K);
}
printf("%d",ans[src][des]); return 0;
}

BZOJ.1875.[SDOI2009]HH去散步(DP 矩阵乘法)的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

  7. BZOJ-1875 HH去散步 DP+矩阵乘法快速幂

    1875: [SDOI2009]HH去散步 Time Limit: 20 Sec Memory Limit: 64 MB Submit: 1196 Solved: 553 [Submit][Statu ...

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

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

  9. [SDOI2009]HH去散步 「矩阵乘法计数」

    计数问题也许可以转化为矩阵乘法形式 比如若该题没有不能在一条边上重复走的条件限制,那么直接将邻接矩阵转化为矩阵乘法即可 故 矩阵乘法计数 对于计数问题,若可以将 \(n\) 个点表示成 \(n \ti ...

随机推荐

  1. 【转载】apache log配置 按日期写日志

    指定apache日志每天生成一个文件 Linux系统配置方法 在apache的配置文件httpd.conf中找到 代码如下1 ErrorLog logs/error_log CustomLog log ...

  2. FarBox--另类有趣的网站服务【转】

    FarBox--另类有趣的网站服务 转自:http://mosir.org/html/y2012/the-interesting-web-service-serve-by-FarBox.html 作者 ...

  3. Nodejs+定时截图+发送邮件

    功能 每天定时截图,并把截到的图片自动通过邮件发送. 说明 代码注释已经非常详细,就不多做说明,需要的朋友自己查看代码即可,主文件Mail.js,截图文件capturePart1.js,capture ...

  4. mysql锁表与不锁表设置主从复制的方法

    有时候MySQL主从同步不一致比较严重的时候,需要手动同步.先说说在锁表的情况下如何操作:以下是其简要过程 1.先对主库锁表FLUSH TABLES WITH READ LOCK; 2.备份数据mys ...

  5. asp.net core 通过ajax上传图片及wangEditor图片上传

    asp.net core 通过ajax上传图片 .net core前端代码,因为是通过ajax调用,首先要保证ajax能调用后台代码,具体参见上一篇.net core 使用ajax调用后台代码. 前端 ...

  6. caffe:fine-tuning

    http://blog.csdn.net/u010402786/article/details/70141261 https://zhuanlan.zhihu.com/p/22624331

  7. wpf 加阴影效果导致内容模糊的问题解决

    这个和GPU有关,参考地址 https://www.cplotts.com/2009/02/25/gpu-effects-blurry-text/ 产生问题的代码如下: <Window x:Cl ...

  8. 【python】已安装模块提示ImportError: No module named

    今天遇到了一个问题,运行代码时出现错误 Traceback (most recent call last): File , in <module> import zmq ImportErr ...

  9. java 类型转换前先做检查

    1.传统的类型转换由RTTI确保正确性. 2.instanceof关键字(二元操作符) ,返回一个Boolean值,告诉我们对象是不是某个类或该类派生类的实例,他判断的是类型. if (a insta ...

  10. js读取xml文件

    假设我们现在要读取下面的 info.xml 文件 <?xml version="1.0" encoding="gb2312"?> <root& ...