题目传送门

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. eclipse 报错:One or more constraints have not been satisfied.

    接受 我有同样的问题.在我的maven项目中添加速度依赖关系后,我在标记选项卡中得到相同的错误.然后我注意到maven项目创建的web.xml文件具有servlet2.3模式.当我将其更改为servl ...

  2. spring boot 应用发布到Harbor上

    具体的harbor配置和docker配置可以查看前面几篇,也包含了我遇到的问题 settings.xml配置 <server> <id>docker-hub</id> ...

  3. [CSP-S模拟测试110]题解

    也许是最后一篇了. A.最大或 不错的签到题. 对于二进制位来说,高位的一个1比低位的所有1的贡献总和还要大. 显然,$r$必选,因为$r$中所有1的相对考前.那么考虑如何构造另一个数. 首先$l$和 ...

  4. wangjunkai

    <!Doctype html><html lang="en"> <head> <meta http-equiv="Content ...

  5. MySQL5.7.21报错:[Err] 1055

    [Err] 1055 - Expression #1 of ORDER BY clause is not in GROUP BY clause and contains nonaggregated c ...

  6. 组件Component详解

    [转]https://www.cnblogs.com/moqiutao/p/8328931.html

  7. 为什么每次打出的包都是Release版本呢?

    参考了:xcodebuild命令 https://www.cnblogs.com/liuluoxing/p/8622108.html 重新打个包,验证一下想法

  8. ELK+Filebeat (1)

    1 Filebeat介绍 Filebeat是Beat成员之一,基于Go语言,无任何依赖,并且比logstash更加轻量,非常适合安装在生产机器上,不会带来过高的资源占用,轻量意味着简单,所以Fileb ...

  9. [Linux] 029 脚本安装包

    1. 脚本安装包 脚本安装包并不是独立的软件包类型,常见安装的是源码包 是人为把安装过程写成了自动安装的脚本,只要执行脚本,定义简单的参数,就可以完成安装 非常类似于 Windows 下软件的安装方式 ...

  10. secureCRT安装,破解,连接linux机器(含安装包)

    1. 为什么需要安装secureCRT 我们的项目运行在服务器上,如果出现什么问题,或者升级的时候,需要对服务器进行操作,把处理好的项目发布到服务器上.如果我们就在服务器身边,那么直接在服务器上进行操 ...