AtCoder Grand Contest 036D - Negative Cycle
神仙题?反正我是完全想不到哇QAQ
这场AGC真的很难咧\(\times 10086\)
\(\bf Description\)
一张 \(n\) 个点的图,\(i\) 到 \(i+1\) 有连边。
现在来了个Snuke,他会给所有 \((i,j) ,i \ne j\) 连边,如果 \(i<j\) ,边权为 \(-1\) ,否则为 \(1\) 。
然鹅Ringo不想要图里有负环,所以他会删去Snuke加的一些边,使得图中没有负环,删除一条边有个代价,问最小的删边代价。\(3 \leq n \leq 500\)
\(\bf Solution\)
(官方题解是从 \(0\) 标号的,我是从 \(1\) 标号的,所以有一点点不一样)
对于一个没有负环的图,我们可以弄出这样一个数组 \(p\) 满足
- 对于任意 \(i\) 到 \(j\) 的边,满足 \(p_j \leq p_i + weight(i,j)\),(weight是权值,不是代价)
显然这个 \(p_i\) 是存在的,比如说是 \(1\) 到 \(i\) 的最短路。
然后令 \(q_i=p_i-p_{i+1}\) ,于是
- 对于一条 \(i → j (i>j)\) 的边,必须满足 \(p_j \leq p_i+1\),即 \(q_j+q_{j+1}+ \cdots + q_{i-1} \leq 1\)
- 对于一条 \(i → j (i<j)\) 的边,必须满足 \(p_j \leq p_i-1\),即 \(q_i+q_{i+1}+ \cdots + q_{j-1} \geq 1\)
可以发现只用考虑 \(0 \leq q_i \leq 1\)的情况 。
现在问题就简单了,对于一个 \(q\) ,只要把不符合上述条件的边都删掉就行。
用 \(f[i][j]\) 长度为 \(j\) 的数组里最后一个 \(1\) 在 \(j\) ,倒数第二个在 \(i\) ,的最小删边代价。(和官方题解是反的)
当我们从 \(f[i][j]\) 转移到 \(f[j][k]\) 时,要删去这样两种边:
- \(b → a \ (b>a), i<a \leq j, b>k\) (因为 \(b\) 到 \(a\) 有两个 \(1\) 了所以就不行)
- \(a → b, j<a<b \leq k\) (因为 \(a\) 到 \(b\) 没有 \(1\) 了所以就不行)
用前缀和就可以 \(O(1)\) 转移啦。
时间复杂度 \(O(n^3)\)
具体实现的话,用 \(w[i][j]\) 表示 \(1 \leq a \leq i , j \leq b \leq n\) ,所有 \(b → a\) 边的权值和
\(vv[i][j]\) 表示 \(i \leq a < b \leq j\) ,所有 \(a → b\) 边的权值和。
预处理一下就可以转移了。
另 \(q_0\) 和 \(q_{n+1}\) 强制为 \(1\) 可以省去对边界的特判。
#include<bits/stdc++.h>
#define LL long long
#define fr(i,x,y) for(int i=(x);i<=(y);i++)
#define rf(i,x,y) for(int i=(x);i>=(y);i--)
#define frl(i,x,y) for(int i=(x);i<(y);i++)
using namespace std;
const int N=505;
const int p=998244353;
int n;
int a[N][N];
LL w[N][N],vv[N][N];
LL f[N][N];
void read(int &x){ scanf("%d",&x); }
void read(LL &x){ scanf("%lld",&x); }
LL vwv(int a,int b,int c){
return w[b][c]-w[a-1][c];
}
void chkmin(LL &x,LL y){
if (y<x) x=y;
}
int main(){
read(n);
fr(i,1,n)
fr(j,1,n)
if (i!=j) read(a[i][j]);
fr(i,1,n)
rf(j,n,i+1){
w[i][j]=w[i][j+1];
fr(k,1,i) w[i][j]+=a[j][k];
}
fr(i,1,n)
fr(j,i+1,n+1){
vv[i][j]=vv[i][j-1];
fr(k,i,j-1) vv[i][j]+=a[k][j];
}
memset(f,0x3f,sizeof f);
f[0][0]=0;
fr(i,0,n)
fr(j,i,n)
if (f[i][j]<1e18){
fr(k,j+1,n+1)
chkmin(f[j][k],f[i][j]+vv[j+1][k]+vwv(i+1,j,k+1));
}
LL ans=1e18;
fr(i,0,n) chkmin(ans,f[i][n+1]);
cout<<ans<<endl;
return 0;
}
AtCoder Grand Contest 036D - Negative Cycle的更多相关文章
- Atcoder Grand Contest 036 D - Negative Cycle
Atcoder Grand Contest 036 D - Negative Cycle 解题思路 在某些情况下,给一张图加或删一些边要使图合法的题目要考虑到最短路的差分约束系统.这一题看似和最短路没 ...
- AtCoder Grand Contest 002
AtCoder Grand Contest 002 A - Range Product 翻译 告诉你\(a,b\),求\(\prod_{i=a}^b i\)是正数还是负数还是零. 题解 什么鬼玩意. ...
- AtCoder Grand Contest 012
AtCoder Grand Contest 012 A - AtCoder Group Contest 翻译 有\(3n\)个人,每一个人有一个强大值(看我的假翻译),每三个人可以分成一组,一组的强大 ...
- AtCoder Grand Contest 011
AtCoder Grand Contest 011 upd:这篇咕了好久,前面几题是三周以前写的... AtCoder Grand Contest 011 A - Airport Bus 翻译 有\( ...
- AtCoder Grand Contest 031 简要题解
AtCoder Grand Contest 031 Atcoder A - Colorful Subsequence description 求\(s\)中本质不同子序列的个数模\(10^9+7\). ...
- AtCoder Grand Contest 010
AtCoder Grand Contest 010 A - Addition 翻译 黑板上写了\(n\)个正整数,每次会擦去两个奇偶性相同的数,然后把他们的和写会到黑板上,问最终能否只剩下一个数. 题 ...
- AtCoder Grand Contest 009
AtCoder Grand Contest 009 A - Multiple Array 翻译 见洛谷 题解 从后往前考虑. #include<iostream> #include< ...
- AtCoder Grand Contest 008
AtCoder Grand Contest 008 A - Simple Calculator 翻译 有一个计算器,上面有一个显示按钮和两个其他的按钮.初始时,计算器上显示的数字是\(x\),现在想把 ...
- AtCoder Grand Contest 007
AtCoder Grand Contest 007 A - Shik and Stone 翻译 见洛谷 题解 傻逼玩意 #include<cstdio> int n,m,tot;char ...
随机推荐
- Redis的持久化机制是什么?各自的优缺点?
Redis 提供两种持久化机制 RDB 和 AOF 机制: 1.RDBRedis DataBase)持久化方式:是指用数据集快照的方式半持久化模式) 记录 redis 数据库的所有键值对,在某个时间点 ...
- Java 学习笔记之 Stop停止线程
Stop停止线程: 使用stop()方法停止线程是非常暴力的,会抛出java.lang.ThreadDeath Error,但是我们无需显示捕捉, 以下捕捉只是为了看得更清晰. public clas ...
- FFmpeg(一)
1. FFmpeg分为3个版本:Static. Shared. Dev 前两个版本可以直接在命令行中使用.包含了三个exe:ffmpeg.exe,ffplay.exe,ffprobe.exe Sta ...
- Python读取excel 数据
1.安装xlrd 2.官网 通过官网来查看如何使用python读取Excel,python excel官网: http://www.python-excel.org/ 实例: (1)Excel内容 把 ...
- 比较两个文件的异同Python3 标准库difflib 实现
比较两个文件的异同Python3 标准库difflib 实现 对于要比较两个文件特别是配置文件的差异,这种需求很常见,如果用眼睛看,真是眼睛疼. 可以使用linux命令行工具diff a_file b ...
- 就个人银行账户管理程序谈谈C++和Java的异同
4_9 同: Java和C++都是面向对象的语言.都有数据成员,方法,访问权限的概念. 异: 访问权限上,非private时Java的默认访问权限是包.而C++的默认访问权限是private.Java ...
- USART_FLAG_TXE和USART_FLAG_TC
在串口数据发送操作中,代码一般是这样写的: void USART_SendByte(USART_TypeDef* USARTx, uint8_t Data) { while(USART_GetFlag ...
- PHP array_slice
1.函数的作用:返回数组中的部分区间的元素 2.函数的参数: @params array $array @params int $offset @params int $l ...
- 网站是HTTP?10分钟变成HTTPS!域名免费添加配置SSL证书,变成https//环境
对于小程序request请求需要https域名.navigator.geolocation定位也需要在https环境下才可以生效等问题: 前端开发越来越需要https环境来来测试一下API接口和各类问 ...
- pytest3-命令行选项
1.pytest -h 查看pytest常用命令 E:\myproj\pytest_demo>pytest -h usage: pytest [options] [file_or_dir] [f ...