【题解】 bzoj1875: [SDOI2009]HH去散步 (动态规划+矩阵乘法)
Solution:
- 看到这道题,看的出是个dp,每个点\(t\)时刻到达的方案数等于\(t-1\)到连过来的点方案数之和
- 但又因为题目有要求不能走一样的边回去不是说不能回到之前那个点,而是不能走一样的边
- 又因为\(t\)很大,每次我们的都是做的重复的操作,我们就可以想到矩阵快速幂
- 为了保证不走重边回去,我们就可以用一个骚操作,把边化作点,然后双向边可以看做两条单向边,然后把每条单向边看做节点,连向所(这条边连向的节点)连出去的边。但是不连这条边的反向边,这样就可以保证不走一样的路回去了(超级机智)

如上图的\(1\)号边连向\(2\)号边,我们就可以把这个存在矩阵里面了 - 然后来一遍矩阵快速幂就好了,注意是\(t-1\)次,因为最后一次没走到,是到边上,没有回到\(B\)点
- 初始矩阵是把\(A\)点所有连出去的边\(+1\),然后把初始矩阵乘以快速幂后的矩阵,\(ans\)就是最后得到矩阵中所有连向\(B\)边上存的值和
- 丢一个我觉得讲的很清楚的博客
Attention:
- 会有重复边,所以矩阵里面是\(+1\),不是直接赋值为\(1\)
- 不能走一样的路回去,可以走另一条路回到先前的点
Code:
//It is coded by Ning_Mew on 5.10
#include<bits/stdc++.h>
#define IL inline
using namespace std;
const int maxn=125,MOD=45989;
int n,m,t,A,B,out=0;
struct Blc{
int a[maxn][maxn];
Blc(){memset(a,0,sizeof(a));}
}bas;
int head[maxn],cnt=0;
struct Edge{
int nxt,to;
}edge[maxn];
void add(int from,int to){
edge[++cnt].nxt=head[from];edge[cnt].to=to;head[from]=cnt;
}
IL int o(int x){if(x%2)return x+1;return x-1;}
IL Blc X(Blc x,Blc y){
Blc ans;
for(int i=1;i<=2*m;i++){
for(int j=1;j<=2*m;j++){
for(int k=1;k<=2*m;k++){
ans.a[i][j]+=x.a[i][k]*y.a[k][j]%MOD;
ans.a[i][j]%=MOD;
}
}
}return ans;
}
IL Blc q_pow(Blc x,int s){
Blc ans=bas;
while(s){
if(s%2)ans=X(ans,x);
x=X(x,x);
s=s/2;
}return ans;
}
int main(){
scanf("%d%d%d%d%d",&n,&m,&t,&A,&B);
for(int i=1;i<=m;i++){
int x,y;scanf("%d%d",&x,&y);
add(x,y);add(y,x);
}
Blc box;
for(int u=0;u<n;u++){
for(int i=head[u];i!=0;i=edge[i].nxt){
int v=edge[i].to;
for(int ii=head[v];ii!=0;ii=edge[ii].nxt){
//cout<<"pr:"<<i<<' '<<ii<<endl;
if(i==o(ii))continue;
bas.a[i][ii]++;
}
}
}
//pr(bas);
for(int i=head[A];i!=0;i=edge[i].nxt){box.a[1][i]++;}
Blc ans=q_pow(bas,t-2);
ans=X(box,ans);
for(int i=1;i<=2*m;i++){
if(edge[i].to==B){out=(out+ans.a[1][i])%MOD;}
}
//cout<<endl;pr(ans);
printf("%d\n",out);
return 0;
}
【题解】 bzoj1875: [SDOI2009]HH去散步 (动态规划+矩阵乘法)的更多相关文章
- BZOJ 1875 [SDOI2009]HH去散步 ——动态规划 矩阵乘法
发现t非常大,所以大概就是快速幂一类的问题了, 然后根据k^3logn算了算,发现k大约是边数的时候复杂度比较合适. 发现比较麻烦的就是前驱的记录,所以直接把边看做点,不能走反向边,但是可以走重边,然 ...
- BZOJ_1875_[SDOI2009]HH去散步_矩阵乘法
BZOJ_1875_[SDOI2009]HH去散步_矩阵乘法 Description HH有个一成不变的习惯,喜欢饭后百步走.所谓百步走,就是散步,就是在一定的时间 内,走过一定的距离. 但 是同时H ...
- [难题题解] [BZOJ1875] [SDOI2009] HH去散步
题目H有个一成不变的习惯,喜欢饭后百步走.所谓百步走,就是散步,就是在一定的时间 内,走过一定的距离. 但是同时HH又是个喜欢变化的人,所以他不会立刻沿着刚刚走来的路走回. 又因为HH是个喜欢变化的人 ...
- 1875. [SDOI2009]HH去散步【矩阵乘法】
Description HH有个一成不变的习惯,喜欢饭后百步走.所谓百步走,就是散步,就是在一定的时间 内,走过一定的距离. 但 是同时HH又是个喜欢变化的人,所以他不会立刻沿着刚刚走来的路走回. 又 ...
- BZOJ 1875: [SDOI2009]HH去散步(矩阵乘法)
首先,题意就把我们引向了矩阵乘法,注意边长m<=60,那么就按边建图,变成一个120个点的图,然后乱搞就行了。 PS:WA了N久改了3次终于A了QAQ CODE: #include<cst ...
- [SDOI2009]HH去散步 「矩阵乘法计数」
计数问题也许可以转化为矩阵乘法形式 比如若该题没有不能在一条边上重复走的条件限制,那么直接将邻接矩阵转化为矩阵乘法即可 故 矩阵乘法计数 对于计数问题,若可以将 \(n\) 个点表示成 \(n \ti ...
- [bzoj1875][SDOI2009] HH去散步 [dp+矩阵快速幂]
题面 传送门 正文 其实就是让你求有多少条长度为t的路径,但是有一个特殊条件:不能走过一条边以后又立刻反着走一次(如果两次经过同意条边中间隔了别的边是可以的) 如果没有这个特殊条件,我们很容易想到dp ...
- BZOJ.1875.[SDOI2009]HH去散步(DP 矩阵乘法)
题目链接 比较容易想到用f[i][j]表示走了i步后到达j点的方案数,但是题目要求不能走上一条走过的边 如果这样表示是不好转移的 可以考虑边,f[i][j]表示走了i步后到达第j条边的方案数,那么有 ...
- BZOJ-1875 HH去散步 DP+矩阵乘法快速幂
1875: [SDOI2009]HH去散步 Time Limit: 20 Sec Memory Limit: 64 MB Submit: 1196 Solved: 553 [Submit][Statu ...
- BZOJ 1875: [SDOI2009]HH去散步( dp + 矩阵快速幂 )
把双向边拆成2条单向边, 用边来转移...然后矩阵乘法+快速幂优化 ------------------------------------------------------------------ ...
随机推荐
- 转自:strcmp函数实现及详解
strcmp函数是C/C++中基本的函数,它对两个字符串进行比较,然后返回比较结果,函数形式如下:int strcmp(constchar*str1,constchar*str2);其中str1和st ...
- VisualSVN server 搭建SVN服务器
最好用VisualSVN server 服务端和 TortoiseSVN客户端搭配使用.
- Android Layout属性笔记
android:id 为控件指定相应的ID android:text 指定控件当中显示的文字,需要注意的是,这里尽量使用strings.xml文件当中的字符串 android:gravity 指定Vi ...
- android学习---Gallery画廊视图
Gallery与Spinner有共同父类:AbsPinner.说明Gallery与Spinner都是一个列表框. 它们之间的差别在于Spinner显示的是一个垂直的列表选择框,而Gallery显示的是 ...
- 解决eth0网卡无法自动加载的问题
问题:输入ifup eth0显示无法加载网卡所在的文件 解决办法: vi /etc/rc.d/rc.local 最后一行加入: ifup eth0 然后重启虚拟机即可解决问题. 本文为博主原创文章,未 ...
- Exp5:MSF基础应用
Exp5:MSF基础应用 一.基础问题回答 (1)用自己的话解释什么是 exploit , payload , encode. exploit: 设相当于利用漏洞偷偷打开的管道,将做好的木马病毒等顺利 ...
- mfc Picture Control 控件属性
知识点: Picture Control 控件属性 CStatic类 图片控件 图片控件使用 一.图片控件属性 Picture Control 属性: Type:Frame //框架 Type:Etc ...
- 4556: [Tjoi2016&Heoi2016]字符串
4556: [Tjoi2016&Heoi2016]字符串 链接 分析: 首先可以二分这个长度.此时需要判断是否存在一个以b结尾的前缀,满足与[c,d]的lcp大于等于mid. 如果我们把串翻转 ...
- manjaro安装软件
fcitx 安装以下包 fcitx-googlepinyin kcm-fcitx 安装了输入法之后,还要在/etc/profile或~/.xprofile里添加如下内容: export GTK_IM_ ...
- thinkphp3.2 批量添加数据
这是我遇到的thinkphp3.2 当中最让我无语的坑 批量添加数据有个方法是 addAll() 这个方法一定要注意数组的键名,一定要整齐!!! 可以在存入数据前,用ksort()方法将数组的键名排序 ...