bzoj4773 负环 倍增+矩阵
时间:2019-09-29
本文章向大家介绍bzoj4773 负环 倍增+矩阵,主要包括bzoj4773 负环 倍增+矩阵使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
题目传送门
https://lydsy.com/JudgeOnline/problem.php?id=4773
题解
最小的负环的长度,等价于最小的 \(len\) 使得存在一条从点 \(i\) 到自己存在一条长度 \(\leq len\) 的负权路径。
为了把 \(\leq len\) 转化为 \(=len\),我们可以给每一个点建立有个边权为 \(0\) 的自环。
所以考虑倍增邻接矩阵,维护两点之间的经过 \(2^i\) 条边的最短路。
倍增的时候判断走了那么多步有没有负环就可以了。
最后结束的时候再判断一次,防止无解。
时间复杂度 \(O(n^3\log n)\)。
#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 = 300 + 7;
const int INF = 0x3f3f3f3f;
int n, m;
struct Matrix {
int a[N][N];
inline Matrix() { memset(a, 0x3f, sizeof(a)); }
inline Matrix(const int &x) {
memset(a, 0x3f, sizeof(a));
for (int i = 1; i <= n; ++i) a[i][i] = x;
}
inline Matrix operator * (const Matrix &b) {
Matrix c;
for (int k = 1; k <= n; ++k)
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= n; ++j)
smin(c.a[i][j], a[i][k] + b.a[k][j]);
return c;
}
} A, B[9];
inline void work() {
B[0] = A, A = Matrix(0);
for (int i = 1; i < 9; ++i) B[i] = B[i - 1] * B[i - 1];
int ans = 0;
for (int i = 8; ~i; --i) {
Matrix C = A * B[i];
int mn = INF;
for (int j = 1; j <= n; ++j) smin(mn, C.a[j][j]);
if (mn >= 0) A = C, ans += 1 << i;
}
A = A * B[0];
int mn = INF;
for (int j = 1; j <= n; ++j) smin(mn, A.a[j][j]);
if (mn >= 0) puts("0");
else printf("%d\n", ans + 1);
}
inline void init() {
read(n), read(m);
int x, y, z;
A = Matrix(0);
for (int i = 1; i <= m; ++i) read(x), read(y), read(z), A.a[x][y] = z;
}
int main() {
#ifdef hzhkk
freopen("hkk.in", "r", stdin);
#endif
init();
work();
fclose(stdin), fclose(stdout);
return 0;
}
原文地址:https://www.cnblogs.com/hankeke/p/bzoj4773.html
- 如何使用scikit-learn在Python中生成测试数据集
- OpenStack Neutron之持续测试
- 干货丨 用 Python 进行股票分析
- 小故事:架构师需要做什么?
- 浅谈用Python计算文本BLEU分数
- Fourinone如何实现并行计算和数据库引擎
- 在Python中用一个长短期记忆网络来演示记忆
- CDA数据分析师学习之路第3期 | Spark RDD的转换操作举例
- 通过Temboo实现从Arduino获取雅虎天气信息
- 自动化模式中的MySQL
- 通过Pandas实现快速别致的数据分析
- R语言中的非线性分类
- 用SPSS做数据分析?先弄懂SPSS的基础知识吧
- 学习笔记CB001:NLTK库、语料库、词概率、双连词、词典
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- LinkedList源码阅读笔记
- RTSP协议网络摄像头接入视频平台EasyNVR
- 在 Hiplot 中使用 Sigflow
- 0805-CDH5中的Parquet迁移至CDP中兼容性验证
- 为什么我的Redis这么“慢”?
- Nginx系列:数据压缩
- Ray,面向新兴AI应用的分布式框架
- 60.Vue export default 和 export 的使用方式
- Idea开发maven插件
- redis实战 migrate异常NOAUTH Authentication required.
- linux内存使用情况分析(free + top)
- Centos7 python3安装
- crontab JAVA_HOME not found
- Centos7 源码安装mysql5.6
- mysql登录时报socket找不到终极解决方案