神仙题?反正我是完全想不到哇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的更多相关文章

  1. Atcoder Grand Contest 036 D - Negative Cycle

    Atcoder Grand Contest 036 D - Negative Cycle 解题思路 在某些情况下,给一张图加或删一些边要使图合法的题目要考虑到最短路的差分约束系统.这一题看似和最短路没 ...

  2. AtCoder Grand Contest 002

    AtCoder Grand Contest 002 A - Range Product 翻译 告诉你\(a,b\),求\(\prod_{i=a}^b i\)是正数还是负数还是零. 题解 什么鬼玩意. ...

  3. AtCoder Grand Contest 012

    AtCoder Grand Contest 012 A - AtCoder Group Contest 翻译 有\(3n\)个人,每一个人有一个强大值(看我的假翻译),每三个人可以分成一组,一组的强大 ...

  4. AtCoder Grand Contest 011

    AtCoder Grand Contest 011 upd:这篇咕了好久,前面几题是三周以前写的... AtCoder Grand Contest 011 A - Airport Bus 翻译 有\( ...

  5. AtCoder Grand Contest 031 简要题解

    AtCoder Grand Contest 031 Atcoder A - Colorful Subsequence description 求\(s\)中本质不同子序列的个数模\(10^9+7\). ...

  6. AtCoder Grand Contest 010

    AtCoder Grand Contest 010 A - Addition 翻译 黑板上写了\(n\)个正整数,每次会擦去两个奇偶性相同的数,然后把他们的和写会到黑板上,问最终能否只剩下一个数. 题 ...

  7. AtCoder Grand Contest 009

    AtCoder Grand Contest 009 A - Multiple Array 翻译 见洛谷 题解 从后往前考虑. #include<iostream> #include< ...

  8. AtCoder Grand Contest 008

    AtCoder Grand Contest 008 A - Simple Calculator 翻译 有一个计算器,上面有一个显示按钮和两个其他的按钮.初始时,计算器上显示的数字是\(x\),现在想把 ...

  9. AtCoder Grand Contest 007

    AtCoder Grand Contest 007 A - Shik and Stone 翻译 见洛谷 题解 傻逼玩意 #include<cstdio> int n,m,tot;char ...

随机推荐

  1. 初识TDD

    什么是 TDD ? TDD 有广义和狭义的区分. 广义角度指的是 ATDD(Acceptance Test Driven Development),包括 BDD(Behavior Driven Tes ...

  2. 设计模式----创建型型模式之单件模式(Singleton pattern)

    单件模式,又称单例模式,确保一个类只有一个实例,并提供全局访问点. 单件模式是比较简单且容易理解的一种设计模式.只有一个实例,通常的做法...TODO 类图比较简单,如下所示: 示例代码: 懒汉模式( ...

  3. 【TencentOS tiny】深度源码分析(3)——队列

    队列基本概念 队列是一种常用于任务间通信的数据结构,队列可以在任务与任务间.中断和任务间传递消息,实现了任务接收来自其他任务或中断的不固定长度的消息,任务能够从队列里面读取消息,当队列中的消息是空时, ...

  4. Java线程状态和关闭线程的正确姿势

    1.线程状态及切换 Java中的线程有六种状态,使用线程Thread内的枚举类来实现,如下,我对每个状态都进行了一定的解释. public enum State { /** 表示一个线程还没启用(即未 ...

  5. HTTP中get和post

    HTTP中get和post的区别 GET - 从指定的资源请求数据. POST - 向指定的资源提交要被处理的数据 GET POST 后退/刷新 无害的 数据会被重新提交 书签 可收藏为书签 不可收藏 ...

  6. unittest中HTMLTestRunner模块生成

    unittest里面是不能生成html格式报告的,需要导入一个第三方的模块:HTMLTestRunner 一.导入HTMLTestRunner 方法1.这个模块下载不能通过pip安装了,只能下载后手动 ...

  7. PMP(第六版)中的各种矩阵表格

  8. SPDK发送和接收连接请求的处理

    因工作需要分析了部分SPDK代码,主要梳理login请求以及响应的处理,供参考. 参考代码——SPDK代码实现(以PLOGI为例): SPDK处理PLOGI分为三个阶段: 第一阶段通过一条GET_PA ...

  9. vue——同一局域网内访问项目

    1.想要在手机上访问本地的vue项目,首先要保证手机和电脑处在同一局域网内(连着同一个无线网) 2.将你电脑的ip设置为固定ip(ipconfig查找本地的ip,然后修改它,改为你想变的数字) 3.在 ...

  10. pytest2-收集与执行测试用例规则

    pytest收集测试用例规则 测试文件以test_开头(以_test结尾也可以) 测试类以Test开头,并且不能带有 init 方法 测试函数以test_开头(以_test结尾也可以) pytest执 ...