bzoj 4773: 负环 floyd
题目:
对于边带权的有向图,找出一个点数最小的环,使得环上的边权和为负.
2 <= n <= 300.
题解:
我们可以考虑从小到大枚举答案.
然后每次枚举更大的答案的时候就从当前的较小的答案更新过去.
更具体一点,可以设f[i][j]表示当前的步数下从i走到j的最短路.
每次更新本质就是一个简单的动态规划的状态转移.
但是这样复杂度是\(O(n^4)\)的.
肯定跑不过去.
更近一步地,从刚才的思路转变一下.
我们设\(f[d][i][j]\)表示\(i \to j\)走\(2^d\)步时的最短路.
我们可以在\(O(n^3\log n)\)的复杂度内预处理出来整个数组.
震惊! \(n^3\log n\)竟可以跑过300 !!!
然后我们利用这个数组将上面的从小到大枚举答案变为类似二分的过程!
也就是说我们可以枚举答案的二进制位.
不难发现如果\((010)_2\)成立那么\((100)_2\)也成立,所以答案具有单调性.
所以二分即可.
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
inline void read(int &x){
    x=0;static char ch;bool flag = false;
    while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
    while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
}
#define rg register int
#define rep(i,a,b) for(rg i=(a);i<=(b);++i)
#define per(i,a,b) for(rg i=(a);i>=(b);--i)
const int maxn = 510;
const int inf = 0x3f3f3f3f;
int dis[9][maxn][maxn];
int f[maxn][maxn],g[maxn][maxn];
int main(){
    int n,m;read(n);read(m);
    int u,v,w;
    rep(i,1,n) rep(j,1,n) if(i != j) dis[0][i][j] = inf;
    rep(i,1,m){
        read(u);read(v);read(w);
        dis[0][u][v] = w;
    }
    rep(d,1,8){
        rep(i,1,n) rep(j,1,n){
            if(i != j) dis[d][i][j] = inf;
            else dis[d][i][j] = 0;
        }
        rep(k,1,n) rep(i,1,n) rep(j,1,n){
            dis[d][i][j] = min(dis[d-1][i][k]+dis[d-1][k][j],dis[d][i][j]);
        }
    }
    rep(i,1,n) rep(j,1,n){
        if(i != j) g[i][j] = inf;
        else g[i][j] = 0;
    }
    bool flag;
    int ans = 0;
    per(d,8,0){
        rep(i,1,n) rep(j,1,n) f[i][j] = g[i][j];
        rep(k,1,n) rep(i,1,n) rep(j,1,n){
            f[i][j] = min(f[i][j],min(g[i][k]+dis[d][k][j],dis[d][i][k]+g[k][j]));
        }
        flag = false;
        rep(i,1,n) if(f[i][i] < 0){
            flag = true;
            break;
        }
        if(flag) continue;
        rep(i,1,n) rep(j,1,n) g[i][j] = f[i][j];
        ans |= 1 << d;
    }
    if(++ans > n) puts("0");
    else printf("%d\n",ans);    return 0;
}
bzoj 4773: 负环 floyd的更多相关文章
- bzoj 4773: 负环——倍增
		Description 在忘记考虑负环之后,黎瑟的算法又出错了.对于边带权的有向图 G = (V, E),请找出一个点数最小的环,使得 环上的边权和为负数.保证图中不包含重边和自环. Input 第1 ... 
- BZOJ 4773: 负环 倍增Floyd
		现在看来这道题就非常好理解了. 可以将问题转化为求两点间经过 $k$ 个点的路径最小值,然后枚举剩余的那一个点即可. #include <cstdio> #include <cstr ... 
- HDU 1217 Arbitrage(Bellman-Ford判断负环+Floyd)
		题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1217 题目大意:问你是否可以通过转换货币从中获利 如下面这组样例: USDollar 0.5 Brit ... 
- 负环 BZOJ 4773
		负环 [问题描述] 在忘记考虑负环之后,黎瑟的算法又出错了.对于边带权的有向图 G = (V, E),请找出一个点数最小的环,使得环上的边权和为负数.保证图中不包含重边和自环. [输入格式] 第1两个 ... 
- 递归型SPFA+二分答案 || 负环 || BZOJ 4773
		题解: 基本思路是二分答案,每次用Dfs型SPFA验证该答案是否合法. 一点细节我注释在代码里了. 代码: #include<cstdio> #include<cstring> ... 
- POJ2240 Arbitrage(Floyd判负环)
		跑完Floyd后,d[u][u]就表示从u点出发可以经过所有n个点回到u点的最短路,因此只要根据数组对角线的信息就能判断是否存在负环. #include<cstdio> #include& ... 
- bzoj 1486: [HNOI2009]最小圈  dfs求负环
		1486: [HNOI2009]最小圈 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 1022 Solved: 487[Submit][Status] ... 
- BZOJ.4500.矩阵(差分约束 SPFA判负环 / 带权并查集)
		BZOJ 差分约束: 我是谁,差分约束是啥,这是哪 太真实了= = 插个广告:这里有差分约束详解. 记\(r_i\)为第\(i\)行整体加了多少的权值,\(c_i\)为第\(i\)列整体加了多少权值, ... 
- BZOJ 4898 [APIO2017] 商旅 | SPFA判负环 分数规划
		BZOJ 4898 [APIO2017] 商旅 | SPFA判负环 分数规划 更清真的题面链接:https://files.cnblogs.com/files/winmt/merchant%28zh_ ... 
随机推荐
- linux集群管理
			本文以ubuntu-16.04.3-server-amd64为例,搭建服务器集群.同样是依托于虚拟机. 创建第一个节点 创建新的虚拟机参见:创建新的虚拟机,创建之后,编辑虚拟机,选择Ubuntu镜像, ... 
- iptables的例子1
			练习1:实现主机防火墙 设置主机防火墙策略为DROP: iptables -t filter -P INPUT DROP iptables -t filter -P OUTPUT DROP i ... 
- Java基础 - 标识符
			标识符就是用来给包,类,方法变量等起名字的符号 组成规则: A:unicode字符 数字字符,英文大小写字母,汉字(不建议使用汉字) B:下划线 _ C:美元符 $ 注意事项: A:不能以数字开头 B ... 
- centos出现-bash: /usr/bin/php: 没有那个文件或目录解决方法
			造成这个的原因是因为找不到php的执行文件导致的,原先我是安装的php5.4,然后卸载了重新安装php7,导致php可执行文件没有放到$PATH中,可以在终端测试:php -v,如果报错bash: / ... 
- Xen虚拟化基础篇
			一.xen的简介 Xen是一个开放源代码虚拟机监视器,由剑桥大学开发.它打算在单个计算机上运行多达128个有完全功能的操作系统. 在旧(无虚拟硬件)的处理器上执行Xen,操作系统必须进行显式地修改(& ... 
- Python socket server demo
			#coding:utf-8 from socket import * #开启ip和端口 ip_port = ("192.168.1.103",8088) print ip_port ... 
- Elatsicsearch分片和副本相关知识
			1.分片和副本 1.1什么是分片 简单来讲就是咱们在ES中所有数据的文件块,也是数据的最小单元块,整个ES集群的核心就是对所有分片的分布.索引.负载.路由等达到惊人的速度. 分片是把索引数据切分成多个 ... 
- Spark Mllib源码分析
			1. Param Spark ML使用一个自定义的Map(ParmaMap类型),其实该类内部使用了mutable.Map容器来存储数据. 如下所示其定义: Class ParamMap privat ... 
- 《python基础教程(第二版)》学习笔记 文件和素材(第11章)
			<python基础教程(第二版)>学习笔记 文件和素材(第11章) 打开文件:open(filename[,mode[,buffering]]) mode是读写文件的模式f=open(r' ... 
- wampserver2 配置ssl 经过验证 可用
			本文原地址 http://blog.csdn.net/taosst/article/details/2182966 http://forum.wampserver.com/read.php?2,329 ... 
