bzoj4386 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
solution
考虑只有边权为1的图。
拿一个矩阵G[i][j]表示i到j有多少走法。他的x次幂就是i走恰好x步到j的情况。
那么小于等于x的怎么求呢。
可以加一个计数点。把所有点向计数点连边,再加一个自环,也就是i-1步的方案也算进i步的方案。
现在考虑边权123
把每个点新建2个虚点,分别为 i+n i+n+n
如果i~j有x的边
连i+(x-1)*n~j
注意爆ll
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#define ll unsigned long long
using namespace std;
int N,n,m;
ll goal;
ll Ans;
struct node{
ll v[][];
void cle(){
for(int i=;i<=N;i++)
for(int j=;j<=N;j++)v[i][j]=;
}
}G,A[],ans,tmp;
node operator *(node A,node B){
node C;C.cle();
for(int i=;i<=N;i++)
for(int j=;j<=N;j++){
for(int k=;k<=N;k++){
C.v[i][j]+=A.v[i][k]*B.v[k][j];
if(C.v[i][j]>1e19){C.v[][]=-;return C;}
}
}
return C;
}
bool pd(){
if(tmp.v[][]<){return ;}
ll sum=;
for(int i=;i<=n;i++){
sum+=(tmp.v[i][N]-);
if(sum>1e19)return ;
//cout<<tmp.v[i][N]<<' ';
}
//cout<<"sum "<<sum<<endl;
return sum<goal;
}
int main(){
cin>>n>>m>>goal;N=n+n+n+;//goal+=n;
for(int i=;i<=n;i++){
G.v[i][i+n]=G.v[i+n][i+n+n]=;
G.v[i][N]=;
}
G.v[N][N]=;
for(int i=,t1,t2,t3;i<=m;i++){
scanf("%d%d%d",&t1,&t2,&t3);
G.v[t1+(t3-)*n][t2]++;
}
A[]=G; for(int i=;i<=;i++)A[i]=A[i-]*A[i-];
for(int i=;i<=n;i++)ans.v[i][i]=;
for(int i=;i>=;i--){
tmp=ans*A[i];
if(pd())ans=tmp,Ans += (1ll << i);
if(i==&&pd()){puts("-1");return ;}
}
cout<<Ans<<endl;
return ;
}
/*
2 1 1
1 2 1 */
bzoj4386 Wycieczki的更多相关文章
- 【BZOJ-4386】Wycieczki DP + 矩阵乘法
4386: [POI2015]Wycieczki Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 197 Solved: 49[Submit][Sta ...
- 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小的路径的长度,注意路径不一定是简单路径,即可以重复走同一个点. 输入 第 ...
- BZOJ4386 [POI2015]Wycieczki 矩阵+倍增
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4386 题解 一眼就可以看出来是邻接矩阵快速幂. 可是这里的边权不为 \(1\).不过可以发现, ...
- Wycieczki 线性代数
B. Wycieczki 题目描述 给定一张n个点m条边的带权有向图,每条边的边权只可能是1,2,3中的一种.将所有可能的路径按路径长度排序,请输出第k小的路径的长度,注意路径不一定是简单路径,即可以 ...
- bzoj 4386: [POI2015]Wycieczki
bzoj 4386: [POI2015]Wycieczki 这题什么素质,爆long long就算了,连int128都爆……最后还是用long double卡过的……而且可能是我本身自带大常数吧,T了 ...
- [POI2015]Wycieczki
题目描述 给定一张n个点m条边的带权有向图,每条边的边权只可能是1,2,3中的一种.将所有可能的路径按路径长度排序,请输出第k小的路径的长度,注意路径不一定是简单路径,即可以重复走同一个点. 输入输出 ...
随机推荐
- finddler的安装与设置
这是抓取手机包的设置 过滤 新安装的,可能还需要证书问题
- RPC框架基础概念理解以及使用初体验
RPC:Remote Procedure Call(远程服务调用) RPC是做什么的 通过RPC框架机器A某个进程可以通过网络调用机器B上的进程方法,就像在本地上调用一样. RPC可以基于HTTP或者 ...
- Linux下常用压缩 解压命令与压缩比率对比
常用的格式有:tar, tar.gz(tgz), tar.bz2, 不同方式,压缩和解压方式所耗CPU时间和压缩比率也差异也比较大. 1. tar只是打包动作,相当于归档处理,不做压缩:解压也一样,只 ...
- Python面向对象--高级(二)
## 使用__slots__限制类的属性 - 之前说到,可以通过在类外部实例或者类名任意定义实例属性或者类属性或者方法 class Person(object): pass Person.name = ...
- Oracle常用傻瓜问题1000问
Oracle常用傻瓜问题1000问 大家在应用ORACLE的时候可能会遇到很多看起来不难的问题, 特别对新手来说, 今天我简单把它总结一下, 发布给大家, 希望对大家有帮助! 和大家一起探讨, 共同进 ...
- redis安装与简单使用
第一步 新建一个文件 第二步 利用winscrp软件从本机上传redis的压缩包到linux新建的rdtar目录 第三步 cd rdtar 第四步 解压 tar zxvf redis-2+t ...
- 【PHP项目】$_SEVER详解
$_SERVER['HTTP_ACCEPT_LANGUAGE']//浏览器语言 $_SERVER['REMOTE_ADDR'] //当前用户 IP . $_SERVER['REMOTE_HOST'] ...
- iOS-delegate设计模式
1. 使用场合 1> A想让B帮忙做一些事情,就让B成为A的代理 2> A想通知一下B发生了某些事情,或者想传递一些数据给B,就让B成为A的代理 3> B想监听A所做的一些事情, 就 ...
- c++ tie,ignore
ignore 一个未指定的类型对象,任何值都可以没有影响地赋值给它.通常使用tie来解压一个元组,作为可以忽略的占位符. #include <iostream> #include < ...
- POJ 2084 Catalan
Game of Connections Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 8772 Accepted: 43 ...