Atcoder Grand Contest 036 D - Negative Cycle

解题思路

在某些情况下,给一张图加或删一些边要使图合法的题目要考虑到最短路的差分约束系统。这一题看似和最短路没什么关系,但有一个不那么经典的推论,对于一个点 \(u\) 不在负环上的一个充要条件是

\[\forall_{\text{Edge }v\rightarrow u} dis(S,v)+weight(v, u)\geq dis(S,u)
\]

其中 \(S\) 是图中任意与 \(u\) 联通的一点。

随便新建一个源点 \(S\),我们令 \(p_i=dis(S,i)\) ,仅考虑原图的链可以得到 \(p_i \geq p_{i+1}\) 。对于任意两点 \(x,y\ (x<y)\) ,新加的边 \((x, y), (y, x)\) 需分别满足 \(p_x-1\geq p_y,p_y+1\geq p_x\) 。这里看似推不下去了然而巧妙差分后能获得非常显然的结论,令 \(q_i=p_i-p_{i+1}\) ,移项可得

\[\sum_{i=x}^{y-1} q_i \geq 1,\sum_{i=x}^{y-1}q_i \leq 1
\]

然后我们可以证明出,\(q_i \in \{0,1\}\),这里比较容易,如果 \(q_i <0\) 原链的差分约束条件就不满足,如果 \(q_i > 0\) 则点 \(i+1\) 存在额外的 \(-1\) 入边 \((v,i+1),v< i\),此时 \(v\) 到 \(i\) 最坏情况可以走一段 \(0\) 链更新,所以 \(q_i\) 最多只能为 \(1\) 。

然后我们就可以考虑 \(q_i\) 的每一位取 \(0\) 还是取 \(1\) ,然后删掉不合法的边,这个过程是可以 \(\text{DP}\) 解决的,对于不满足 \(\sum q_i \leq 1\) 的情况,在其跨过第二个 \(1\) 的时候统计掉,对于 \(\sum q_i \geq 1\) 的情况,对于每一段连续的 \(0\) 统计即可,那么就可以令 \(dp[i][j]\) 为当前考虑到前 \(i\) 位且 \(i\) 选 \(1\),上一个 \(1\) 在 \(j\) 的答案,转移使用前缀和优化即可。

code

  1. /*program by mangoyang*/
  2. #include<bits/stdc++.h>
  3. #define inf (0x7f7f7f7f)
  4. #define Max(a, b) ((a) > (b) ? (a) : (b))
  5. #define Min(a, b) ((a) < (b) ? (a) : (b))
  6. typedef long long ll;
  7. using namespace std;
  8. template <class T>
  9. inline void read(T &x){
  10. int ch = 0, f = 0; x = 0;
  11. for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = 1;
  12. for(; isdigit(ch); ch = getchar()) x = x * 10 + ch - 48;
  13. if(f) x = -x;
  14. }
  15. const int N = 505;
  16. #define int ll
  17. int A[N][N], B[N][N], C[N][N], D[N][N], dp[N][N], n;
  18. signed main(){
  19. read(n);
  20. for(int i = 1; i <= n; i++){
  21. for(int j = 1; j < i; j++) read(A[j][i]);
  22. for(int j = i + 1; j <= n; j++) read(B[i][j]);
  23. }
  24. for(int i = 0; i <= n + 1; i++)
  25. for(int j = i; j <= n + 1; j++){
  26. if(i) C[i][j] += C[i-1][j];
  27. for(int k = j; k <= n + 1; k++) C[i][j] += A[i][k];
  28. }
  29. for(int i = n + 1; i >= 0; i--)
  30. for(int j = i; j <= n + 1; j++){
  31. D[i][j] += D[i+1][j];
  32. for(int k = i; k <= j; k++) D[i][j] += B[i][k];
  33. }
  34. memset(dp, 0x3f, sizeof(dp));
  35. dp[0][0] = 0;
  36. for(int i = 1; i <= n + 1; i++)
  37. for(int j = 0; j < i; j++){
  38. for(int k = 0; k <= j; k++)
  39. dp[i][j] = min(dp[i][j], dp[j][k] + C[j][i+1] - C[k][i+1] + D[j+1][i]);
  40. }
  41. int ans = inf;
  42. for(int i = 0; i <= n; i++)
  43. ans = min(ans, dp[n+1][i]);
  44. cout << ans << endl;
  45. return 0;
  46. }

Atcoder Grand Contest 036 D - Negative Cycle的更多相关文章

  1. AtCoder Grand Contest 036 A-C

    目录 \(\bf A - Triangle\) \(\bf B - Do\ Not\ Duplicate\) \(\bf C - GP 2\) \(\bf D - Negative \ Cycle\) ...

  2. AtCoder Grand Contest 036

    Preface 这篇已经鸽了好久的说,AGC037都打完了才回来补所以题目可能都记不大清楚了,如有错误请指正 这场感觉难度远高于上一场,从D开始就不会了,E没写(看了题解都不会写),F就是抄曲明姐姐的 ...

  3. AtCoder Grand Contest 036 简要题解

    从这里开始 比赛目录 Problem A Triangle 考虑把三角形移到和坐标轴相交,即 然后能够用坐标比较简单地计算面积,简单构造一下就行了. Code #include <bits/st ...

  4. AtCoder Grand Contest 036题解

    传送门 爆炸的比较厉害--果然还是菜啊-- \(A\) 我们强制一个点为\((0,0)\),那么设剩下两个点分别为\((a,b),(c,d)\),根据叉积可以计算出面积为\(ad-bc=S\),那么令 ...

  5. AtCoder Grand Contest 002

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

  6. AtCoder Grand Contest 012

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

  7. AtCoder Grand Contest 011

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

  8. AtCoder Grand Contest 031 简要题解

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

  9. AtCoder Grand Contest 010

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

随机推荐

  1. LOJ6609 无意识的石子堆【加强版】【容斥原理,计数】

    题目描述:在一个\(n\times m\)的网格中,放\(2n\)个棋子,使每一行和每一列都不超过两个棋子.求方案数\(\mathrm{mod} \ 943718401\). 数据范围:\(n\le ...

  2. 微信小程序组件化开发框架WePY

    wepy-CLI 安装 npm install -g wepy-cli wepy init standard my-project https://github.com/Tencent/wepy 特性 ...

  3. Java基础教程--安卓入门教程(七)

    关注我,每天都有优质技术文章推送,工作,学习累了的时候放松一下自己. 欢迎大家关注我的微信公众号:「醉翁猫咪」 什么是接口? 接口的基本语法 接口的基本语法(一) 使用interface定义 接口当中 ...

  4. mysql 组合聚集函数

    mysql> select * from table1; +----------+------------+-----+---------------------+ | name_new | t ...

  5. 刷题记录:[ByteCTF 2019]EZCMS

    目录 刷题记录:[ByteCTF 2019]EZCMS 一.知识点 1.源码泄露 2.MD5长度扩展攻击 3.php://filter绕过正则实现phar反序列化 刷题记录:[ByteCTF 2019 ...

  6. 剑指offer:左旋转字符串

    题目描述: 汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运算结果.对于一个给定的字符序列S,请你把其循环左移K位后的序列输出.例如,字符序列S=”ab ...

  7. Linux /var/log下各种日志文件

    Linux /var/log下各种日志文件:

  8. Java多个线程顺序打印数字

    要求 启动N个线程, 这N个线程要不间断按顺序打印数字1-N. 将问题简化为3个线程无限循环打印1到3 方法一: 使用synchronized 三个线程无序竞争同步锁, 如果遇上的是自己的数字, 就打 ...

  9. Nginx正向代理设置

    Nginx不仅可以做反向代理,实现负载均衡.还能用作正向代理来进行上网等功能. 正向代理:如果把局域网外的Internet想象成一个巨大的资源库,则局域网中的客户端要访问Internet,则需要通过代 ...

  10. 数据分析入门——pandas之合并函数merge

    merge有点类似SQL中的join,可以将不同数据集按照某些字段进行合并,得到新的数据集  1.参数一览表: 2.一对一连接:默认情况下,会按照相同字段的进行连接 例如有相同字段emp的两个df,m ...