题目传送门

https://lydsy.com/JudgeOnline/problem.php?id=4386

题解

一眼就可以看出来是邻接矩阵快速幂。

可是这里的边权不为 \(1\)。不过可以发现,边权最多为 \(3\)。但是边的数量很多,不适合拆边,那就拆点吧。对于一条 \(x \to y\) 的边,就建立一个 \(x_0\to y_{w - 1}\) 的边,\(w\) 为边权。

然后就建立矩阵就可以了。因为我们需要统计第 \(i\) 步之前一共有多少路径,所以可以新建一个节点,每个点向这个点连一条有向边,这个点自己再来一个自环。

然后预处理 \(B_i\) 为走了 \(2^i\) 步的矩阵,直接倍增出来答案就可以了。


下面是代码,矩阵乘法的复杂度为 \(O(n^3)\),一共倍增 \(O(\log k)\) 次,因此总的时间复杂度为 \(O(n^3\log k)\)。

#include<bits/stdc++.h>

#define fec(i, x, y) (int i = head[x], y = g[i].to; i; i = g[i].ne, y = g[i].to)
#define dbg(...) fprintf(stderr, __VA_ARGS__)
#define File(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
#define fi first
#define se second
#define pb push_back template<typename A, typename B> inline char smax(A &a, const B &b) {return a < b ? a = b , 1 : 0;}
template<typename A, typename B> inline char smin(A &a, const B &b) {return b < a ? a = b , 1 : 0;} typedef long long ll; typedef unsigned long long ull; typedef std::pair<int, int> pii; template<typename I>
inline void read(I &x) {
int f = 0, c;
while (!isdigit(c = getchar())) c == '-' ? f = 1 : 0;
x = c & 15;
while (isdigit(c = getchar())) x = (x << 1) + (x << 3) + (c & 15);
f ? x = -x : 0;
} const int N = 40 * 3 + 7; int n, m;
ll k; struct Matrix {
ll a[N][N];
inline Matrix() { memset(a, 0, sizeof(a)); } inline Matrix operator * (const Matrix &b) {
Matrix c;
for (int k = 0; k <= n; ++k)
for (int i = 0; i <= n; ++i)
for (int j = 0; j <= n; ++j)
c.a[i][j] += a[i][k] * b.a[k][j];
return c;
} inline void print() const {
for (int i = 0; i <= n; ++i) {
for (int j = 0; j <= n; ++j) dbg("%lld ", a[i][j]);
dbg("\n");
}
}
} A, B[N]; inline bool isfull(const Matrix &a) {
ll cnt = 0;
for (int i = 1; i <= n / 3; ++i) {
cnt += a.a[i][0] - 1;
if (cnt >= k) return 1;
}
return 0;
} inline void work() {
n = n * 3, B[0] = A;
int lim = 0;
for (int i = 1; i <= 70; ++i) {
B[i] = B[i - 1] * B[i - 1];
++lim;
if (isfull(B[i])) break;
}
if (!isfull(B[lim--])) {
puts("-1");
return;
}
memset(A.a, 0, sizeof(A.a));
for (int i = 0; i <= n; ++i) A.a[i][i] = 1;
ll ans = 0;
for (int i = lim; ~i; --i) {
const Matrix &tmp = A * B[i];
if (!isfull(tmp)) A = tmp, ans += 1ll << i;
}
printf("%lld\n", ans);
} inline void init() {
read(n), read(m), read(k);
for (int i = 1; i <= m; ++i) {
int x, y, z;
read(x), read(y), read(z);
if (z == 1) ++A.a[x][y];
if (z == 2) ++A.a[x][y + n];
if (z == 3) ++A.a[x][y + n * 2];
}
for (int i = 1; i <= n; ++i) A.a[i][0] = A.a[i + n][i] = A.a[i + n * 2][i + n] = 1;
A.a[0][0] = 1;
} int main() {
#ifdef hzhkk
freopen("hkk.in", "r", stdin);
#endif
init();
work();
fclose(stdin), fclose(stdout);
return 0;
}

BZOJ4386 [POI2015]Wycieczki 矩阵+倍增的更多相关文章

  1. BZOJ4386[POI2015]Wycieczki——矩阵乘法+倍增

    题目描述 给定一张n个点m条边的带权有向图,每条边的边权只可能是1,2,3中的一种.将所有可能的路径按路径长度排序,请输出第k小的路径的长度,注意路径不一定是简单路径,即可以重复走同一个点. 输入 第 ...

  2. 【bzoj4386】[POI2015]Wycieczki 矩阵乘法

    题目描述 给定一张n个点m条边的带权有向图,每条边的边权只可能是1,2,3中的一种.将所有可能的路径按路径长度排序,请输出第k小的路径的长度,注意路径不一定是简单路径,即可以重复走同一个点. 输入 第 ...

  3. BZOJ4386 : [POI2015]Wycieczki

    将每个点拆成三个点,并将转移转化为矩阵乘法,然后倍增即可求出第$k$短路的长度,注意对爆long long情况的处理. 时间复杂度$O(n^3\log k)$. #include<cstdio& ...

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

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

  5. BZOJ 4386 Luogu P3597 [POI2015]Wycieczki (矩阵乘法)

    题目链接: (bzoj) https://www.lydsy.com/JudgeOnline/problem.php?id=4386 (luogu) https://www.luogu.org/pro ...

  6. 【BZOJ-4386】Wycieczki DP + 矩阵乘法

    4386: [POI2015]Wycieczki Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 197  Solved: 49[Submit][Sta ...

  7. bzoj 4386: [POI2015]Wycieczki

    bzoj 4386: [POI2015]Wycieczki 这题什么素质,爆long long就算了,连int128都爆……最后还是用long double卡过的……而且可能是我本身自带大常数吧,T了 ...

  8. UVa 11149 矩阵的幂(矩阵倍增法模板题)

    https://vjudge.net/problem/UVA-11149 题意: 输入一个n×n矩阵A,计算A+A^2+A^3+...A^k的值. 思路: 矩阵倍增法. 处理方法如下,一直化简下去直到 ...

  9. [POI2015]Wycieczki

    题目描述 给定一张n个点m条边的带权有向图,每条边的边权只可能是1,2,3中的一种.将所有可能的路径按路径长度排序,请输出第k小的路径的长度,注意路径不一定是简单路径,即可以重复走同一个点. 输入输出 ...

随机推荐

  1. 路由Vue-router 的使用总结

    1.关于 router-view 匹配 vue 项目使用 vue-router,所有的根级别的路由都是在 App.vue 文件中的 router-view 中渲染的.比如下面的 path: '/' . ...

  2. 继续写高精!noip2012国王游戏。。。

    国王游戏 题目描述: 恰逢 H 国国庆,国王邀请 n 位大臣来玩一个有奖游戏.首先,他让每个大臣在左.右手上面分别写下一个整数,国王自己也在左.右手上各写一个整数.然后,让这 n 位大臣排成一排,国王 ...

  3. igserver许可证过期 & 发布服务客户端浏览出现error2032

    1.卸载igserver重装 卸载包IGServerForDotNet成功! 卸载包IGServerCore成功! 卸载包MiddleWare_ArcGIS成功! 卸载包SDE_DM成功! 卸载包SD ...

  4. js数组声明+split()方法

    split()方法:var words = sentence.split(' '): "hello".split("", 3) //可返回 ["h&q ...

  5. php面试专题---MySQL分区

    php面试专题---MySQL分区 一.总结 一句话总结: mysql的分区操作还比较简单,好处是也不用自己动手建表进行分区,和水平分表有点像 1.mysql分区简介? 一个表或索引-->N个物 ...

  6. docker 保存镜像 加载镜像

    1.保存镜像 docker save -o 保存的文件名  来源镜像 2.加载镜像 docker load -i 保存的文件名

  7. day08—css布局解决方案之多列布局

    转行学开发,代码100天——2018-03-24 本文将记录CSS布局之垂直布局解决方案. 常见的多列布局包括以下: 1.定宽+自适应 2.两列定宽+一列自适应 3.不定宽+自适应 4.两列不定宽+一 ...

  8. Postman 测试Xfire webservice

    权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/u013177381/article/det ...

  9. MySQL replace into 与insert into

    https://blog.csdn.net/helloxiaozhe/article/details/77427266 使用replace带来的问题 1.Replace into 操作在唯一键重复情况 ...

  10. 编程语言 - PHP

    环境搭建 Window7+Apache24+PHP7. Apache24配置 LoadModule php7_module "D:/SoftWare/php-7.2.21-Win32-VC1 ...