【bzoj4386】[POI2015]Wycieczki 矩阵乘法
题目描述
给定一张n个点m条边的带权有向图,每条边的边权只可能是1,2,3中的一种。
将所有可能的路径按路径长度排序,请输出第k小的路径的长度,注意路径不一定是简单路径,即可以重复走同一个点。
输入
第一行包含三个整数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。
可能有重边。
输出
包含一行一个正整数,即第k短的路径的长度,如果不存在,输出-1。
样例输入
6 6 11
1 2 1
2 3 2
3 4 2
4 5 1
5 3 1
4 6 3
样例输出
4
题解
矩阵乘法
如果边长只为1的话,很容易想到使用矩阵乘法解决。把邻接矩阵的$2^i$记录,直到路径条数足够为止。此时需要统计的是路径长度小于等于某数的路径数,因此新建一个计数器,每个点向它连边,然后计数器连一个自环即可。然后按照倍增LCA的方法按$i$从大到小处理即可。
那如果边长为2或3呢?可以考虑拆点解决(不能拆边因为边数过多,无法矩乘)。对于每个点再建两个辅助节点并连边,分别代表长度为2、3,长度为2时从第一个辅助节点连出去,长度为3时从第二个辅助节点连出去,即可得到答案。
这里嘴上说着真容易= =
事实上,本题会爆long long特别多。因为边数是点数的指数级别的。所以判路径是否超过k时很复杂,正解的话需要在矩乘里面写,外面判断时也要写,非常的复杂。
好在本题数据弱,因此不需要在矩乘里面写,直接在外部判断即可。
时间复杂度$O(n^3\log k)$。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
ll m;
int n;
struct data
{
ll v[121][121];
ll* operator[](int a) {return v[a];}
data operator*(data &a)const
{
int i , j , k;
data ans;
for(i = 0 ; i <= 3 * n ; i ++ )
for(j = 0 ; j <= 3 * n ; j ++ )
ans[i][j] = 0;
for(i = 0 ; i <= 3 * n ; i ++ )
for(j = 0 ; j <= 3 * n ; j ++ )
for(k = 0 ; k <= 3 * n ; k ++ )
ans[i][j] += v[i][k] * a[k][j];
return ans;
}
bool check()
{
ll ret = 0;
int i;
for(i = 1 ; i <= n ; i ++ )
if((ret += v[i][0] - 1) >= m)
return 1;
return 0;
}
}A[70] , Now , Tmp;
bool judge(data &x , data &y , data &z)
{
data tmp = x * y;
if(tmp[0][0] == -1) return 0;
int i;
ll ret = 0;
for(i = 1 ; i <= n ; i ++ )
if((ret += tmp[i][0]) >= m)
return 0;
z = tmp;
return 1;
}
int main()
{
int q , i , x , y , z;
ll ans = 0;
scanf("%d%d%lld" , &n , &q , &m);
A[0][0][0] = 1;
for(i = 1 ; i <= n ; i ++ ) Now[i][i] = A[0][i][0] = A[0][i][i + n] = A[0][i + n][i + 2 * n] = 1;
for(i = 1 ; i <= q ; i ++ ) scanf("%d%d%d" , &x , &y , &z) , A[0][x + (z - 1) * n][y] ++ ;
for(i = 1 ; ; i ++ )
{
if(i > 65)
{
puts("-1");
return 0;
}
A[i] = A[i - 1] * A[i - 1];
if(A[i].check()) break;
}
for(i -- ; ~i ; i -- )
{
Tmp = Now * A[i];
if(!Tmp.check()) Now = Tmp , ans += (1ll << i);
}
printf("%lld\n" , ans);
return 0;
}
【bzoj4386】[POI2015]Wycieczki 矩阵乘法的更多相关文章
- BZOJ4386[POI2015]Wycieczki——矩阵乘法+倍增
题目描述 给定一张n个点m条边的带权有向图,每条边的边权只可能是1,2,3中的一种.将所有可能的路径按路径长度排序,请输出第k小的路径的长度,注意路径不一定是简单路径,即可以重复走同一个点. 输入 第 ...
- BZOJ4386 [POI2015]Wycieczki 矩阵+倍增
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4386 题解 一眼就可以看出来是邻接矩阵快速幂. 可是这里的边权不为 \(1\).不过可以发现, ...
- BZOJ 4386 Luogu P3597 [POI2015]Wycieczki (矩阵乘法)
题目链接: (bzoj) https://www.lydsy.com/JudgeOnline/problem.php?id=4386 (luogu) https://www.luogu.org/pro ...
- BZOJ4386 : [POI2015]Wycieczki
将每个点拆成三个点,并将转移转化为矩阵乘法,然后倍增即可求出第$k$短路的长度,注意对爆long long情况的处理. 时间复杂度$O(n^3\log k)$. #include<cstdio& ...
- BZOJ4386[POI2015]Wycieczki / Luogu3597[POI2015]WYC - 矩乘
Solution 想到边权为$1$的情况直接矩乘就可以得出长度$<=t$ 的路径条数, 然后二分check一下即可 但是拓展到边权为$2$,$3$ 时, 需要新建节点 $i+n$ 和 $i+2n ...
- 【BZOJ-4386】Wycieczki DP + 矩阵乘法
4386: [POI2015]Wycieczki Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 197 Solved: 49[Submit][Sta ...
- bzoj 4386: [POI2015]Wycieczki
bzoj 4386: [POI2015]Wycieczki 这题什么素质,爆long long就算了,连int128都爆……最后还是用long double卡过的……而且可能是我本身自带大常数吧,T了 ...
- *HDU2254 矩阵乘法
奥运 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submissi ...
- *HDU 1757 矩阵乘法
A Simple Math Problem Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Ot ...
随机推荐
- iOS 制作表格 (数据源控制行,列数)
记得去年面试的过程中,有一个面试官问我怎么制作表格.由于之前也没有做过,当时有点懵逼,今天想起来了,就用tableview制作了一个,望不要有人像我一样掉坑了, 直接上代码: // // ViewCo ...
- 【SQL】连接 —— 内连接、外连接、左连接、右连接、交叉连接
连接 · 内连接 · 外连接 · 左连接 · 右连接 · 全连接 · 交叉连接 · 匹配符号(+) 连接 根据表之间的关系,呈现跨表查询的结果. 外连接 内连接 左连接 右连接 全 ...
- NSCopying
///< .h @interface ChatManager : NSObject <NSCopying> @property (nonatomic) NSUInteger inde ...
- 四、Shell 数组
Shell 数组 数组中可以存放多个值.Bash Shell 只支持一维数组(不支持多维数组),初始化时不需要定义数组大小(与 PHP 类似). 与大部分编程语言类似,数组元素的下标由0开始. She ...
- PHP判断时关于null,0,true,flase的值
<?php// $wh = 0; //等于整数0,等于字符串'0',等于空字符串,等于空格字符串, 等于空(null),等于字符串('null')// $wh = '0'; //=>等于整 ...
- commons-logging日志实现解耦
一.需要解耦 日志是实际应用中的一个重要部分,日志系统也有许多开源的实现,如java.util.logging, logback, log4j系列等. 在使用日志系统时,如果与具体 ...
- TI C6000优化手册——让代码看起来像钉子
DSP芯片的出现,是为了解决大量的数字运算问题.通过集成专用的加法器.乘法器.地址产生器.复杂逻辑等硬件单元,DSP能实现比普通单片机更快速的数字运算,使处理器更适用于实时性高.复杂度强的处理场合.也 ...
- HOJ_14001 Just Terraffic!
题意相对来说比较扭曲..所以来说下模型,具体做法有兴趣的孩纸去问度娘或者波塞冬吧~~ 给出一个序列长度,并且输入该序列,该序列的含义是横坐标: 任何两个相邻坐标绝对值小于等于1000的必然为一个整体, ...
- Linux命令之---diff
命令介绍 diff命令可以酌行比较纯文本文件内的内容,并输出文件的差异. 命令格式 diff [option] [file1] [file2] 举例子 1)比较俩文本文件 [root@king ~]# ...
- Java文件 ---文件相关操作
创建文件 file.createNewFile() 注:若该文件对象未指定文件路径,则文件创建于相对路径中,即工程目录下.(“../”表示上级文件目录,相对路径前面不加“/”,eg:bin/text. ...