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 ...
随机推荐
- 由std::once_call 引发的单例模式的再次总结,基于C++11
一个偶然的机会,知道了std::once_call这个东西. 了解了下,std::once_call支持多线程情况下的某函数只执行一次.咦,这个不是恰好符合单例模式的多线程安全的困境吗? 单例模式,经 ...
- 快学Scala 第七课 (类构造函数)
类 主构造器: class Person (var name: String){ } 主构造参数可以不带val或者var,如果没有被其他方法使用,则不保存为字段. 如果被其他方法使用,则被升格为字段, ...
- PHP 通过 ReflectionMethod 反射类方法获取注释返回 false 的问题解决
php 通过反射 ReflectionMethod 类来获取类方法的相关信息,其中就包含方法的注释内容. 问题描述 在公司测试环境运行以下代码,如果是 cli 命令行模式运行,正常输出代码注释.如果是 ...
- 10个值得深思的_PHP_面试问题
Q1 第一个问题关于弱类型 $str1 = 'yabadabadoo'; $str2 = 'yaba'; if (strpos($str1,$str2)) { echo "\"&q ...
- 从0开始学FreeRTOS-(任务调度)-4
大家晚上好,我是杰杰,最近挺忙的,好久没有更新了,今天周末就吐血更新一下吧! # 前言 `FreeRTOS`是一个是实时内核,任务是程序执行的最小单位,也是调度器处理的基本单位,移植了`FreeRTO ...
- python编程基础之三十五
系统的魔术方法:系统的魔术方法特别多,但是也都特别容易懂,简单的讲就是对系统的内置函数进行重写,你需要什么效果就重写成什么样, 比如说len()方法针对的对象本来没有自定义类的对象,但是当你重写了__ ...
- python编程基础之二
交互式: 此处以windows为例:开始->运行->cmd,输入python 交互式界面 优点:即时,所见即所得 缺点:代码不可复用,根本无法进行维护 退出:exit() 代码是顺序执行: ...
- 跑的比谁都快 51Nod - 1789
香港记者跑的比谁都快是众所周知的常识. 现在,香港记者站在一颗有 nn 个点的树的根结点上(即1号点),编号为 ii 的点拥有权值 a[i]a[i] ,数据保证每个点的编号都小于它任意孩子结 ...
- sql获取各种时间格式的方法
),)--月/日/年 ),)--年.月.日 (常用) ),)--日/月/年 ),)--日.月.年 ),)--日-月-年 ),)--日 月 年
- 洛谷P1608 路径计数
题目简介 题目描述 给你一个N点M边的有向图,求第一个点到第n个点的最短路和最短路条数 题目分析 很明显直接Dijkstra求最短路,加一个最短路计数 如下: if(dis[y]>dis[x]+ ...