也许更好的阅读体验

Description\mathcal{Description}Description
给定一张n个点m条边的带权有向图,每条边的边权只可能是1,2,3中的一种。将所有可能的路径按路径长度排序,请输出第k小的路径的长度,注意路径不一定是简单路径,即可以重复走同一个点。
(1≤n≤40,1≤m≤1000,1≤k≤1018)(1\leq n\leq 40,1\leq m\leq 1000,1\leq k\leq 10^{18})(1≤n≤40,1≤m≤1000,1≤k≤1018)

Solution\mathcal{Solution}Solution
死毒瘤题,打了一晚上,最后把自己的方法改的和其他人差不多了
边权不为111,不好直接套用邻接矩阵,考虑把一个点拆开,让一条长度大于111的路径要到一些没用的点使得它需要走多次才能走到它该到的点
把一个点nnn拆为n0,n1,n2n_0,n_1,n_2n0​,n1​,n2​,分别表示距离nnn还有0/1/20/1/20/1/2的距离,实际上,n0n_0n0​就是原本的点,我们称之为实点,n1,n2n_1,n_2n1​,n2​则是用来消耗路径长度的点,称之为虚点
先有n2→n1,n1→n0n_2\ \rightarrow\ n_1,n_1\ \rightarrow \ n_0n2​ → n1​,n1​ → n0​连边
对一条边(u,v,w)\left(u,v,w\right)(u,v,w),考虑由实点u0u_0u0​走出去一步,那么距离vvv就会减一,所以u0u_0u0​向vw−1v_{w-1}vw−1​连一条边,即连边(u0,vw−1)\left(u_0,v_{w-1}\right)(u0​,vw−1​)

现在我们可以对现在的矩阵做乘法和快速幂了,每个实点到实点的权值就是方案数
如现在是这个矩阵的kkk次方,则矩阵上(u0,v0)\left(u_0,v_0\right)(u0​,v0​)上的权值表示的就是从u0u_0u0​出发,走kkk步走到v0v_0v0​的方案数

接下来考虑怎么求答案,kkk很大,自然地就想到了倍增,类似求LCALCALCA一样的去确定答案即可

当然,直接对矩阵求ppp次方,那么求出来的矩阵里的值表示的是刚好走ppp步从某个位置走到某个位置的答案
为了方便的进行判断,我们需要把矩阵的值表示成走小于等于ppp步的方案数
所以要考虑把走过的答案存下来,我们可以用000号点表示所有的方案数
怎么用000号点表示呢,考虑每次算出一个值后再算下一个值时将当前的答案放到000号点去
所以对每个点实点u0u_0u0​连一条(u0,0)\left(u_0,0\right)(u0​,0)的边即可,而每次计算不能把上次的答案丢了,所以还要连一条(0,0)\left(0,0\right)(0,0)的边

这样当前矩阵的000号点就表示着上一次的答案
我们再弄一个矩阵乘上当前矩阵就可以表示,这个矩阵000向所有的实点连一条边即可

Code\mathcal{Code}Code

/*******************************
Author:Morning_Glory
LANG:C++
Created Time:2019年11月06日 星期三 18时58分03秒
*******************************/
#include <cstdio>
#include <fstream>
#define ll long long
#define ld long double
#define rint register int
using namespace std;
const int maxn = 130;
//{{{cin
struct IO{template<typename T>IO & operator>>(T&res){res=0;bool flag=false;char ch;while((ch=getchar())>'9'||ch<'0')   flag|=ch=='-';while(ch>='0'&&ch<='9')  res=(res<<1)+(res<<3)+(ch^'0'),ch=getchar();if (flag) res=~res+1;return *this;}
}cin;
//}}}
int n,lim,m;
ll k,ans;
//{{{Matrix
struct Matrix{ld mat[maxn][maxn];Matrix (bool opt=0){for (int i=0;i<=lim;++i)for (int j=0;j<=lim;++j)    mat[i][j]=opt&&(i==j);}ld* operator [] (const int &x){   return mat[x];}Matrix operator * (Matrix &b){Matrix a=*this,s;for (int i=0;i<=lim;++i)for (int j=0;j<=lim;++j)for (int k=0;k<=lim;++k)s[i][j]+=a[i][k]*b[k][j];return s;}
}g[maxn],s;
//}}}
inline int loc (int x,int i){   return (x-1)*3+i+1;}
inline ld sum (Matrix &a) { return a[0][0]-n; }
int main()
{freopen("p3597.in","r",stdin);freopen("p3597.out","w",stdout);cin>>n>>m>>k;lim=3*n;for (rint i=1;i<=n;++i){for (rint j=1;j<=2;++j)    g[0][loc(i,j)][loc(i,j-1)]=1;g[0][loc(i,0)][0]=s[0][loc(i,0)]=1;}g[0][0][0]=1;for (rint i=1;i<=m;++i){int u,v,d;cin>>u>>v>>d;++g[0][loc(u,0)][loc(v,d-1)];}int d;for (d=1;;++d){g[d]=g[d-1]*g[d-1];Matrix t=s*g[d];if (sum(t)>=k)   break;if (d>=64)    return printf("-1\n"),0;}for (rint i=d;~i;--i){Matrix t=s*g[i];if (sum(t)<k){s=t;ans+=(1ll<<i);}}printf("%lld\n",ans);return 0;
}

如有哪里讲得不是很明白或是有错误,欢迎指正
如您喜欢的话不妨点个赞收藏一下吧

POI2015 WYC相关推荐

  1. #倍增+矩阵乘法# [luogu P3597] [POI2015]WYC

    Title P3597 [POI2015]WYC Solution 注意这道题code中的一些细节 这道题做的我人都傻了,关键是有两种理解,但是关系不大. .. f[k][i][k]f[k][i][k ...

  2. [Luogu P3597] [BZOJ 4386] [POI2015]WYC

    洛谷传送门 BZOJ传送门 题目描述 给定一张nnn个点mmm条边的带权有向图,每条边的边权只可能是111,222,333中的一种.将所有可能的路径按路径长度排序,请输出第kkk小的路径的长度,注意路 ...

  3. BZOJ4386[POI2015]Wycieczki / Luogu3597[POI2015]WYC - 矩乘

    Solution 想到边权为$1$的情况直接矩乘就可以得出长度$<=t$ 的路径条数, 然后二分check一下即可 但是拓展到边权为$2$,$3$ 时, 需要新建节点 $i+n$ 和 $i+2n ...

  4. P6772-[NOI2020]美食家【矩阵乘法,倍增】

    前言 我考场(线上赛)切NOI的题了! 正题 题目链接:https://www.luogu.com.cn/problem/P6772 题目大意 nnn个点mmm条边,每个城市有不同的愉悦值,从111出 ...

  5. [最新]免费伪原创SEO接口推荐

    文章目录[隐藏] 前言 接口地址 接口参数说明 前言 其实市面上有很多的伪原创接口,但是许多接口都是收费的,最近在搜索时找到一个免费的接口感觉挺不错的推荐给大家. 接口地址 http://seowyc ...

  6. 【BZOJ 3747】 3747: [POI2015]Kinoman (线段树)

    3747: [POI2015]Kinoman Time Limit: 60 Sec  Memory Limit: 128 MB Submit: 830  Solved: 338 Description ...

  7. [POI2015]CZA

    [POI2015]CZA p很小,讨论 p=0... p=1... p=2:n-1放左或者放右两种情况,剩下怎么放是固定的,模拟然后判断即可 p=3: 正着做要状压,类似放书和排座位那些题,考虑以某个 ...

  8. P3591 [POI2015]ODW(分块)

    P3591 [POI2015]ODW 给定一颗有nnn个节点的树,点有点权,给定一个长度为nnn的排列ppp,给定一个长度为n−1n - 1n−1的数组ccc, 我们会在树上进行n−1n - 1n−1 ...

  9. bzoj4380[POI2015]Myjnie dp

    [POI2015]Myjnie Time Limit: 40 Sec  Memory Limit: 256 MBSec  Special Judge Submit: 368  Solved: 185 ...

最新文章

  1. Elastic Job从单点到高可用、同城主备、同城双活
  2. 表分区MySQL版本:5.5.11比5.1查询速度明显提高(4倍左右)
  3. Python面向对象进阶及类成员
  4. 绿色计算在数据中心的应用及节能效果浅析
  5. 《Programming WPF》学习(二)Application及其设置
  6. ASP.NET Core loves JavaScript
  7. 1822. 数组元素积的符号
  8. git为私有仓库设置密码_真香!在局域网下行云流水般使用git
  9. 为什么eolinker发送老是等待_eolinker之初体验
  10. Oracle归档日志管理
  11. 9.jsonp的实现原理
  12. 运行错误代码_Win7系统提示错误代码0xc0000135应该如何解决?
  13. 抢购 mysql 优化_处理抢购、秒杀应用场景降低“超卖”发生几个优化方案(php)...
  14. c语言利用循环结构解决密码转换,C语言课件第六章循环结构.ppt
  15. 2022年 超详细的Android(安卓)入门编程教程
  16. MySQL-5.5-winx64 安装包下载
  17. 最公正海贼王实力排行TOP50!
  18. jyhtfkuy5987tgoluigl.kjylghliuygliuylio
  19. python获取股票_python根据股票代码获取当前数据
  20. linux centos 手册,zh/FAQ/CentOS4 - CentOS Wiki

热门文章

  1. 敏捷,文档,人才,文化——谈小公司研发管理
  2. 【编程游戏】贺岁霓虹灯。(参观261楼dh20156的霓虹灯)
  3. tp监控连接云路由服务器失败_TP ID提示发送请求失败怎么办?TP-Link ID发送请求失败现象的原因及解决方案...
  4. 需要时才去度秘一下,不如苍老师主动找你服务一下
  5. Linux内核:kmalloc()和SLOB、SLAB、SLUB内存分配器
  6. 实验4 调制解调的matlab实现
  7. 学什么专业才能成为程序员?其实想成为程序员,远不止计科和软工!
  8. 银河麒麟V10(arm64) 源码编译Qt5.8.0
  9. 对静态数据成员进行初始化
  10. 抖音表情包小程序项目