【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^ ...
随机推荐
- Python的高级特性11:拓展基本数据类型(dict)
字典的创建有两种方式,如果出现In [26]这样的赋值方式就会报错. In [17]: s['name'] = 'alex' In [18]: s['sex'] = 'male' In [19]: s ...
- 查看Mysql实时执行的Sql语句
最近给客户开发了基于Asp.Net mvc5 +Mysql+EF的项目,但是在EF里无法看到Mysql执行的语句 之前也找到一些监控Mysql的软件但一直没有用起来,现在又遇到了问题即在EF里Mysa ...
- ASP.NET MVC使用jQuery来POST数据至数据库中
学习ASP.NET MVC程序,结合jQuery客户端代码,Post数据至数据库去.Insus.NET今天写一个完整性的例子. 在数据库中,创建一个表[dbo].[TestUser]: 既然是把数据存 ...
- [转]JS调用Android里面的方法,Android调用JS里面的方法
FROM : http://blog.csdn.net/hj563308597/article/details/45197709 Android WebView 在公司Android的开发过程中遇到一 ...
- codevs2693 上学路线(施工)
难度等级:黄金 2693 上学路线(施工) 题目描述 Description 问题描述 你所在的城市街道好像一个棋盘,有a条南北方向的街道和b条东西方向的街道. 南北方向a条街道从西到东依次编号为1到 ...
- oracle: job使用
oracle的job,实际上就是数据库内置的定时任务,类似代码中的Timer功能.下面是使用过程: 这里我们模拟一个场景:定时调用存储过程P_TEST_JOB 向表TEST_JOB_LOG中插入数据 ...
- spring mvc4:异常处理
前面学习过struts2的异常处理,今天来看下spring mvc4的异常处理: 一.Servlet配置文件修改 <bean id="exceptionResolver" c ...
- 谱多流形聚类SMMC
今天是2015年的最后一天,决定尽量乘着这三天休息把毕设主题的博客给更完,今天写smmc的算法,接下来三天会对前面的三个算法kmeans.SC以及smmc应用在今年的研究生建模提供的数据中进行matl ...
- .Net Core 自定义序列化格式
序列化对大家来说应该都不陌生,特别是现在大量使用WEBAPI,JSON满天飞,序列化操作应该经常出现在我们的代码上. 而我们最常用的序列化工具应该就是Newtonsoft.Json,当然你用其它工具类 ...
- C# 调用一个按钮的Click事件(利用反射)
最基本的调用方法 (1)button1.PerformClick();(2)button1_Click(null,null);(3)button_Click(null,new EventArgs()) ...