[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。
输入输出样例
输入样例#1:
6 6 11
1 2 1
2 3 2
3 4 2
4 5 1
5 3 1
4 6 3
输出样例#1:
4
说明
给定一张n个点m条边的带权有向图,每条边的边权只可能是1,2,3中的一种。
将所有可能的路径按路径长度排序,请输出第k小的路径的长度,注意路径不一定是简单路径,即可以重复走同一个点。
题解
矩乘(倍增?)
如果边权都是1,把每个点都连向计数点
然后对矩阵做k次快速幂就表示路径长度<=k的路径条数
边权很小一看就可以想到拆点(\([SCOI2009]\)迷路)
对于每个点 , 拆成三个点
第一个点是实点
后两个点是虚点
因为每次转移都只能转移一步表示走一步,这一步长度为1
所以拆点后对于\((u,v,w)\)就相当于转移\(w\)次才能通过这条路径从\(u->v\)
然后再把每个实点和计数点\((n*3+1)\)连一条边方便计数
由于一条路径长度不一定等于转移次数
所以再让计数器形成一个自环
这样转移t次后统计计数器的答案表示的就是路径长度<=t的路径条数
然后如果二分路径长度然后\(check\)的话会T
所以用类似于倍增的方法
预处理出这个矩阵转移\(2^i\)次后的矩阵
每次处理\(2^i\)的矩阵完成后\(check\)一下,如果大于k个就可以停止了
然后再倍增求答案
从大往小里枚举
像倍增跳LCA那样,每当蹦到一个总路径条数<k的状态,就把当前状态更新成那个状态,并加上相应的答案
代码
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
# define int long long
const int M = 125 ;
const int N = 70 ;
using namespace std ;
inline int read() {
char c = getchar() ; int x = 0 , w = 1 ;
while(c>'9'||c<'0') { if(c=='-') w = -1 ; c = getchar() ; }
while(c>='0'&&c<='9') { x = x*10+c-'0' ; c = getchar() ; }
return x * w ;
}
int n , m , E , kth , Ans ;
struct Matrix {
int f[M][M] ;
inline Matrix () { memset(f , 0 , sizeof(f)) ; }
inline void Start() { for(int i = 1 ; i <= E ; i ++) f[i][i] = 1 ; }
inline friend Matrix operator * (Matrix a , Matrix b) {
Matrix temp ;
for(int i = 1 ; i <= E ; i ++)
for(int j = 1 ; j <= E ; j ++)
for(int k = 1 ; k <= E ; k ++)
temp.f[i][j] = (temp.f[i][j] + a.f[i][k] * b.f[k][j]) ;
return temp ;
}
inline bool chk() {
int ret = 0 ;
for(int i = 1 ; i <= n ; i ++) {
ret = (ret + f[i][E] - 1) ;
if(ret >= kth || ret < 0)
return true ;
}
return false ;
}
} st[N] , Now , Temp ;
# undef int
int main() {
# define int long long
n = read() ; m = read() ; kth = read() ; E = n * 3 + 1 ; st[0].f[E][E] = 1 ;
for(int i = 1 ; i <= n ; i ++) st[0].f[i][E] = st[0].f[i][i + n] = st[0].f[i + n][i + n * 2] = 1 ;
for(int i = 1 , u , v , w ; i <= m ; i ++) {
u = read() , v = read() , w = read() ;
st[0].f[u + (w - 1) * n][v] ++ ;
}
int Maxup ;
for(int i = 1 ; i <= 63 ; i ++) {
if(i == 63) { printf("-1\n") ; return 0 ; }
st[i] = st[i - 1] * st[i - 1] ;
if(st[i].chk()) { Maxup = i ; break ; }
}
Now.Start() ;
for(int i = Maxup ; i >= 0 ; i --) {
Temp = Now * st[i] ;
if(Temp.chk()) continue ;
Now = Temp ; Ans += (1LL << i) ;
}
cout << Ans << endl ;
return 0 ;
}
[POI2015]Wycieczki的更多相关文章
- bzoj 4386: [POI2015]Wycieczki
bzoj 4386: [POI2015]Wycieczki 这题什么素质,爆long long就算了,连int128都爆……最后还是用long double卡过的……而且可能是我本身自带大常数吧,T了 ...
- 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 ...
- BZOJ4386[POI2015]Wycieczki——矩阵乘法+倍增
题目描述 给定一张n个点m条边的带权有向图,每条边的边权只可能是1,2,3中的一种.将所有可能的路径按路径长度排序,请输出第k小的路径的长度,注意路径不一定是简单路径,即可以重复走同一个点. 输入 第 ...
- 【bzoj4386】[POI2015]Wycieczki 矩阵乘法
题目描述 给定一张n个点m条边的带权有向图,每条边的边权只可能是1,2,3中的一种.将所有可能的路径按路径长度排序,请输出第k小的路径的长度,注意路径不一定是简单路径,即可以重复走同一个点. 输入 第 ...
- 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 矩阵+倍增
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4386 题解 一眼就可以看出来是邻接矩阵快速幂. 可是这里的边权不为 \(1\).不过可以发现, ...
- 【BZOJ-4386】Wycieczki DP + 矩阵乘法
4386: [POI2015]Wycieczki Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 197 Solved: 49[Submit][Sta ...
- POI2015题解
POI2015题解 吐槽一下为什么POI2015开始就成了破烂波兰文题目名了啊... 咕了一道3748没写打表题没什么意思,还剩\(BZOJ\)上的\(14\)道题. [BZOJ3746][POI20 ...
随机推荐
- 593. Valid Square
Problem statement: Given the coordinates of four points in 2D space, return whether the four points ...
- UVA 10603_Fill
题意: 给定三个杯子容量,初始只有第三个杯子满,其余为空,求最少需要倒多少水才能让某一杯子中有d升水,如果不能达到,则小于d且尽量接近. 分析: 因为要求转移水量最少,所以采用优先级队列保存每次的状态 ...
- HTTPS 是如何保证安全的?
每当我们讨论到信息安全的时候,我们最长接触到的信息加密传输的方式莫过于 HTTPS 了,当我们浏览器地址栏闪现出绿色时,就代表着这个网站支持 HTTPS 的加密信息传输方式,并且你与它的连接确实被加密 ...
- jmeter的Classpath即类或者jar包的搜索路径设置
对于master-slave模式,插件和依赖都需要放到slave上才能生效,并且需要重启slave使插件生效 查看配置文件:apache-jmeter-3.1/bin/jmeter.propertie ...
- DELPHI、FLASH、AS3、FLEX使用Protobuf(google Protocol Buffers)的具体方法
最近因为工作需要,需要在不同的开发环境中应用Protobuf,特此,我专门研究了一下.为了防止自己忘记这些事情,现在记录在这里!需要的朋友可以借鉴一些,因为这些东西在GOOGLE和百度上搜索起来真的很 ...
- golang 跨平台编译——go 在windows上编译Linux平台的程序(Cross Compilation from Windows to Linux/Ubuntu)
Go Cross Compilation from Windows to Linux/Ubuntu I have GO 1.7 installed on my Windows 10. I create ...
- Mariadb 主从
一 mariadb主从多用于网站架构,因为该主从的同步机制是异步的,数据的同步有一定延迟,也就是说有可能会造成数据的丢失,但是性能比较好,因此网站大多数用的是主从架构的数据库,读写分离必须基于主从架构 ...
- 为什么有些信号线串接33R小电阻?
本人只是刚入坑的硬件助理,一名小白,很多都知识不懂,以下信息多数来自网络,可能不准确,恳请批评指正! 正文: 参考资料:http://blog.csdn.net/xiangyuqxq/article/ ...
- HDU1236 排名 题解
Problem Description 今天的上机考试尽管有实时的Ranklist,但上面的排名仅仅是依据完毕的题数排序,没有考虑 每题的分值,所以并非最后的排名.给定录取分数线.请你敲代码找出最后 ...
- Grails边做边学入门篇[1]--------大家一起来动手建立project和Domain
近期工作比較忙,没空写博客了.我发现每周五的下午都是我最放松的时候,可能是迟延症的缘故吧...总是寄希望于周末,慢慢的.我的周末就被工作占领了. 希望大家不要有这种坏毛病.今日事,今日毕.当然我们程序 ...