【BZOJ-4386】Wycieczki DP + 矩阵乘法
4386: [POI2015]Wycieczki
Time Limit: 20 Sec Memory Limit: 128 MB
Submit: 197 Solved: 49
[Submit][Status][Discuss]
Description
给定一张n个点m条边的带权有向图,每条边的边权只可能是1,2,3中的一种。
将所有可能的路径按路径长度排序,请输出第k小的路径的长度,注意路径不一定是简单路径,即可以重复走同一个点。
Input
第一行包含三个整数n,m,k(1<=n<=40,1<=m<=1000,1<=k<=10^18)。
接下来m行,每行三个整数u,v,c(1<=u,v<=n,u不等于v,1<=c<=3),表示从u出发有一条到v的单向边,边长为c。
可能有重边。
Output
包含一行一个正整数,即第k短的路径的长度,如果不存在,输出-1。
Sample Input
1 2 1
2 3 2
3 4 2
4 5 1
5 3 1
4 6 3
Sample Output
HINT
长度为1的路径有1->2,5->3,4->5。
长度为2的路径有2->3,3->4,4->5->3。
长度为3的路径有4->6,1->2->3,3->4->5,5->3->4。
长度为4的路径有5->3->4->5。
Source
Solution
边权只有1,2,3三种,可以考虑拆点,那么只有边权为1的边了
那么显然可以DP,但是时间复杂度不允许
考虑用矩阵乘法去转移
这里比较优秀的方法是基于倍增的矩阵乘法
总复杂度是$O(n^{3}logK)$
答案会很大,乘爆longlong需要特判
这题细节非常多!
Code
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
inline long long read()
{
long long x=,f=; char ch=getchar();
while (ch<'' || ch>'') {if (ch=='-') f=-; ch=getchar();}
while (ch>='' && ch<='') {x=x*+ch-''; ch=getchar();}
return x*f;
}
#define MAXN 130
int id[MAXN][],ID,N,M,B;
long long K,V[MAXN*];
struct MatrixNode{long long a[MAXN][MAXN];}a[],b,c,tmp;
MatrixNode operator * (const MatrixNode &A,const MatrixNode &B)
{
MatrixNode C; memset(C.a,,sizeof(C.a));
for (int i=; i<=ID; i++)
for (int j=; j<=ID; j++)
for (int k=; k<=ID; k++)
if (A.a[i][k]&&B.a[k][j])
{
if (A.a[i][k]< || B.a[k][j]<) {C.a[i][j]=-; break;}
if (A.a[i][k]>K/B.a[k][j]) {C.a[i][j]=-; break;}
C.a[i][j]+=A.a[i][k]*B.a[k][j];
if (C.a[i][j]>K) {C.a[i][j]=-; break;}
}
return C;
}
bool Check()
{
long long re=;
for (int i=; i<=ID; i++)
if (tmp.a[][i] && V[i])
{
if (tmp.a[][i]<) return ;
if (tmp.a[][i]>K/V[i]) return ;
re+=tmp.a[][i]*V[i];
if (re>K) return ;
}
return re<K;
}
int main()
{
N=read(),M=read(),K=read();
for (int i=; i<=N; i++) for (int j=; j<=; j++) id[i][j]=++ID;
for (int i=; i<=N; i++)
{
for (int j=; j<=; j++)
a[].a[id[i][j]][id[i][j+]]++;
a[].a[][id[i][]]++;
}
a[].a[][]++;
for (int x,y,z,i=; i<=M; i++) x=read(),y=read(),z=read(),a[].a[id[y][z-]][id[x][]]++,V[id[y][z-]]++;
for (int i=; (1LL<<i)<=K*; B=++i); B--;
for (int i=; i<=B; i++) a[i]=a[i-]*a[i-];
long long ans=;
for (int i=; i<=ID; i++) c.a[i][i]=;
for (int i=B; ~i; i--)
{
tmp=c*a[i];
if (Check()) ans|=(1LL<<i),memcpy(c.a,tmp.a,sizeof(tmp.a));
}
ans++;
if (ans>K*) {puts("-1"); return ;}
else printf("%lld\n",ans);
return ;
}
模拟赛的时候,没认真读题,以为是“魔法猪学院”类似的...等到半场才发现.....然后GG
【BZOJ-4386】Wycieczki DP + 矩阵乘法的更多相关文章
- 【bzoj2004】[Hnoi2010]Bus 公交线路 状压dp+矩阵乘法
题目描述 小Z所在的城市有N个公交车站,排列在一条长(N-1)km的直线上,从左到右依次编号为1到N,相邻公交车站间的距离均为1km. 作为公交车线路的规划者,小Z调查了市民的需求,决定按下述规则设计 ...
- 【bzoj3329】Xorequ 数位dp+矩阵乘法
题目描述 输入 第一行一个正整数,表示数据组数据 ,接下来T行每行一个正整数N 输出 2*T行第2*i-1行表示第i个数据中问题一的解, 第2*i行表示第i个数据中问题二的解, 样例输入 1 1 样例 ...
- 【BZOJ 3326】[Scoi2013]数数 数位dp+矩阵乘法优化
挺好的数位dp……先说一下我个人的做法:经过观察,发现这题按照以往的思路从后往前递增,不怎么好推,然后我就大胆猜想,从前往后推,发现很好推啊,维护四个变量,从开始位置到现在有了i个数 f[i]:所有数 ...
- bzoj 3329: Xorequ【数位dp+矩阵乘法】
注意第一问不取模!!! 因为a+b=a|b+a&b,a^b=a|b-a&b,所以a+b=a^b+2(a&b) x^3x==2x可根据异或的性质以转成x^2x==3x,根据上面的 ...
- BZOJ 3329 Xorequ 数字DP+矩阵乘法
标题效果:特定n,乞讨[1,n]内[1,2^n]差多少x满足x^3x=2x x^3x=2x相当于x^2x = 3x 和3x=x+2x 和2x=x<<1 因此x满足条件IFFx&(x ...
- 【BZOJ】1009: [HNOI2008]GT考试(dp+矩阵乘法+kmp+神题)
http://www.lydsy.com/JudgeOnline/problem.php?id=1009 好神的题orzzzzzzzzzz 首先我是连递推方程都想不出的人...一直想用组合来搞..看来 ...
- bzoj 4818: [Sdoi2017]序列计数【容斥原理+dp+矩阵乘法】
被空间卡的好惨啊---- 参考:http://blog.csdn.net/coldef/article/details/70305596 容斥,\( ans=ans_{没有限制}-ans{没有质数} ...
- Luogu P4643 【模板】动态dp(矩阵乘法,线段树,树链剖分)
题面 给定一棵 \(n\) 个点的树,点带点权. 有 \(m\) 次操作,每次操作给定 \(x,y\) ,表示修改点 \(x\) 的权值为 \(y\) . 你需要在每次操作之后求出这棵树的最大权独立集 ...
- LOJ.6074.[2017山东一轮集训Day6]子序列(DP 矩阵乘法)
题目链接 参考yww的题解.本来不想写来但是他有一些笔误...而且有些地方不太一样就写篇好了. 不知不觉怎么写了这么多... 另外还是有莫队做法的...(虽然可能卡不过) \(60\)分的\(O(n^ ...
随机推荐
- linux svn
1.回滚 一直在找svn回滚的方法,这个还是很实用的,屡试不爽阿 经常由于坑爹的需求,功能要切回到之前的某一个版本.有两种方法可以实现: 方法1: 用svn merge 1) 先 svn up,保证 ...
- Ubuntu终端命令行不显示颜色
在网上找到的一个有效方案是在.bash_profile 中增加颜色定义 export LS_COLORS='di=01;35:ln=01;36:pi=40;33:so=01;35:do=01;35:b ...
- div+css兼容 ie6_ie7_ie8_ie9_ie10和FireFox_Chrome等浏览器方法
1.div的垂直居中问题 vertical-align:middle; 将行距增加到和整个DIV一样高 line-height:200px; 然后插入文字,就垂直居中了.缺点是要控制内容不要换行 ...
- python里的del变量无法立刻释放内存的解决办法
最近在python开发的时候,用到了一些很占用内存的操作,导致后续程序执行很慢甚至无法执行.探索了一下,最终解决了这个问题. 截图解释: python变量占用了内存,仅仅通过del变量的方式,只是让这 ...
- 产品需求文档(PRD)的写作方法之笔记一
1.写前准备(思维导图): http://www.woshipm.com/?p=80070 1.在写之前,请先很区分清楚什么是MRD文档(市场需求文档),BRD文档(商业需求文档),什么是PRD文档( ...
- css中如何设置字体
来自百度的回答: 建议使用font-family: "Microsoft YaHei";支持UTF-8和GB2312字符集. 不生效的3种情况:1.当此属性定义的是全局样式时,对于 ...
- 金山快盘+TortoiseSVN构建版本控制仓库
金山会盘+TortoiseSVN构建版本控制仓库 之前写过一篇文章介绍 如何利用花生壳和VisualSVN Server建立远程代码仓库,具体请参照: <如何利用花生壳和VisualSVN Se ...
- Qt学习笔记 QMessageBox
Qt的几种MessageBox 1.Infomation类型 QMessageBox::information(this,tr("hello"),tr("title&qu ...
- Spring IOC 源码浅析
控制反转(Inversion of Control,英文缩写为IoC)是一个重要的面向对象编程的法则来削减计算机程序的耦合问题,也是轻量级的Spring框架的核心. 控制反转一般分为两种类型,依赖注入 ...
- VS条件断点的一个坑
今天早上要调试一个方法,所以在方法的入口处也就是’{’打了一个条件断点,可是随后就发现对这个方法的调用都无法获得正确的结果了,不管传递什么参数,方法的返回值都一样,而且这个返回值与输入的参数完全无关, ...