题目链接

https://atcoder.jp/contests/agc036/tasks/agc036_d

题解

这都是怎么想出来的啊。。目瞪口呆系列。。

第一步转化至关重要: 一张图中不存在负环意味着什么?

不存在负环就存在最短路,我们可以给每个点分配一个权值\(p_i\)(相当于从\(1\)号到该点的最短路,点从\(1\)开始标号)满足对于任何边\((i,j)\)有\(p_j\ge p_i+w(i,j)\).

然后我们令\(q_i=p_i-p_{i+1}\), 那么由于边权都是\(1\)或者\(-1\)并且存在不能删的\(0\)边, 显然有\(q\)数组的值都是\(0\)或者\(1\).

约束变成了: 对于每条边\((i,j)\ (i>j)\)有\(\sum^{i-1}_{k=i}q_k\le 1\), 对于每条边\((i,j)\ (i<j)\)有\(\sum^{j-1}_{k=i}q_k\ge 1\).

所以问题就被转化成了: 你要给每个\(1\)到\((n-1)\)中的点\(q_i\)分配一个\(0\)或者\(1\)的权值,再删掉所有不满足约束条件的边,使得总代价最小!

天哪,这也太神仙了吧……

然后就是一个很容易的DP了,设\(dp[i][j]\)表示安排好前\(i\)位的\(q\)值,且强行令\(q_i=1\), 上一个为\(1\)的位置是\(j\)

那么考虑枚举\(k\), \(dp[i][j]\)转移到\(dp[k][i]\),同时删去不合法的边

对于\(a>b\)的边\((a,b)\), 要删掉所有满足\(j<b\le i<x<a\)的边

对于\(a<b\)的边\((a,b)\), 要删掉所有满足\(j<i<a<b\le x\)的边

然后这个很容易使用二维前缀和优化,时间复杂度\(O(n^3)\).

啊啊啊人类智慧……

代码

  1. #include<cstdio>
  2. #include<cstdlib>
  3. #include<cstring>
  4. #include<cassert>
  5. #include<iostream>
  6. #define llong long long
  7. using namespace std;
  8. inline int read()
  9. {
  10. int x=0; bool f=1; char c=getchar();
  11. for(;!isdigit(c);c=getchar()) if(c=='-') f=0;
  12. for(; isdigit(c);c=getchar()) x=(x<<3)+(x<<1)+(c^'0');
  13. if(f) return x;
  14. return -x;
  15. }
  16. const int N = 500;
  17. llong a[N+3][N+3];
  18. llong s[2][N+3][N+3];
  19. llong dp[N+3][N+3];
  20. int n;
  21. void update(llong &x,llong y) {x = x<y?x:y;}
  22. llong getsum(int typ,int lx,int rx,int ly,int ry)
  23. {
  24. return s[typ][rx][ry]-s[typ][lx-1][ry]-s[typ][rx][ly-1]+s[typ][lx-1][ly-1];
  25. }
  26. int main()
  27. {
  28. scanf("%d",&n);
  29. for(int i=1; i<=n; i++)
  30. {
  31. for(int j=1; j<=n; j++)
  32. {
  33. if(j==i) continue;
  34. scanf("%lld",&a[i][j]);
  35. }
  36. }
  37. for(int i=1; i<=n; i++)
  38. {
  39. for(int j=1; j<=n; j++)
  40. {
  41. if(i<j) {s[0][i][j] = a[i][j];}
  42. s[0][i][j] += s[0][i][j-1];
  43. }
  44. for(int j=1; j<=n; j++) s[0][i][j] += s[0][i-1][j];
  45. }
  46. for(int i=1; i<=n; i++)
  47. {
  48. for(int j=1; j<=n; j++)
  49. {
  50. if(i>j) {s[1][i][j] = a[i][j];}
  51. s[1][i][j] += s[1][i][j-1];
  52. }
  53. for(int j=1; j<=n; j++) s[1][i][j] += s[1][i-1][j];
  54. }
  55. memset(dp,42,sizeof(dp));
  56. dp[0][0] = 0ll;
  57. for(int i=0; i<=n; i++)
  58. {
  59. for(int j=0; j<max(i,1); j++)
  60. {
  61. for(int k=i+1; k<=n; k++)
  62. {
  63. llong tmp = dp[i][j]+getsum(1,k+1,n,j+1,i)+getsum(0,i+1,k,i+1,k);
  64. update(dp[k][i],tmp);
  65. }
  66. }
  67. }
  68. llong ans = dp[n][1];
  69. for(int i=1; i<=n; i++) update(ans,dp[n][i]);
  70. printf("%lld\n",ans);
  71. return 0;
  72. }

AtCoder AGC036D Negative Cycle (图论、DP)的更多相关文章

  1. @atcoder - AGC036D@ Negative Cycle

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 给定一个 N 个点的有向带权图,从 0 编号到 N - 1.一开 ...

  2. Atcoder Grand Contest 036 D - Negative Cycle

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

  3. AtCoder Grand Contest 036D - Negative Cycle

    神仙题?反正我是完全想不到哇QAQ 这场AGC真的很难咧\(\times 10086\) \(\bf Description\) 一张 \(n\) 个点的图,\(i\) 到 \(i+1\) 有连边. ...

  4. 图论+dp poj 1112 Team Them Up!

    题目链接: http://poj.org/problem?id=1112 题目大意: 有编号为1~n的n个人,给出每个人认识的人的编号,注意A认识B,B不一定认识A,让你将所有的人分成两组,要求每组的 ...

  5. atcoder B - Frog 2 (DP)

    B - Frog 2 Time Limit: 2 sec / Memory Limit: 1024 MB Score : 100100 points Problem Statement There a ...

  6. atcoder A - Frog 1(DP)

    A - Frog 1 Time Limit: 2 sec / Memory Limit: 1024 MB Score : 100100 points Problem Statement There a ...

  7. 洛谷P3953 逛公园 [noip2017] 图论+dp

    正解:图论(最短路)+dp(记忆化搜索) 解题报告: 这题真的是个好东西! 做了这题我才发现我的dij一直是错的...但是我以前用dij做的题居然都A了?什么玄学事件啊...我哭了TT 不过其实感觉还 ...

  8. Atcoder E - RGB Sequence(dp)

    题目链接:http://arc074.contest.atcoder.jp/tasks/arc074_c 题意:一共有3种颜色,红色,绿色,蓝色.给出m个要求l,r,x表示在区间[l,r]内要有x种不 ...

  9. AtCoder AGC019E Shuffle and Swap (DP、FFT、多项式求逆、多项式快速幂)

    题目链接 https://atcoder.jp/contests/agc019/tasks/agc019_e 题解 tourist的神仙E题啊做不来做不来--这题我好像想歪了啊= =-- 首先我们可以 ...

随机推荐

  1. vue-router动态路由设置参数可选

    在日常工作中,我们需要将匹配到的所有路由,映射到一个组件上. 如下代码想要达到的效果: 不传page和id,则映射到user默认list页面 传page和id,根据page不同,显示不同的页面 问题 ...

  2. server001

  3. [转载]汇编语言assume伪指令的作用

    原文:https://blog.csdn.net/u010234808/article/details/38366943 摘出关键部分: 编写程序,是写给编译软件的.由编译软件,编译成机器码,再去控制 ...

  4. iview表单验证之正则验证、函数验证

    iview表单验证之正则 正则验证: 代码: loginRules: { stringLength: [ { required: true, message: '该字段不能为空', trigger: ...

  5. 设置VMware 以及指定 虚拟机 ,开机自启动

    进入开机自启动目录 C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp 重命名为 start.bat 编辑 这个文件,编辑之后Ct ...

  6. fiddler抓包小技巧之自动保存抓包数据(可根据需求过滤)

    首先 选择 如果有别的提示的话,你就按着提示走,就会安装一个编辑器,叫Fiddler Script. 正常情况下,你按着上面操作之后就会出现如下界面: 完事了之后,按下Ctrl+F来查找OnBefor ...

  7. no input file specified 三种解决方法

    一.IIS Noinput file specified 方法一:改PHP.ini中的doc_root行,打开ini文件注释掉此行,然后重启IIS 方法二: 请修改php.ini 找到 ; cgi.f ...

  8. kubesphere集群搭建(多节点)

    kubesphere官网:https://kubesphere.io/docs/advanced-v2.0/zh-CN/introduction/intro/ 一.准备环境 1.准备服务器 maste ...

  9. docker_facenet_image在Docker容器中运行Facenet环境搭建

    对开发和运维人员来说,可能最梦寐以求的就是一次性地创建或配置,可以在任意环境.任意时间让应用正常运行.而Docker恰恰是可以实现这一终极目标的瑞士军刀. 具体来说,Docker在开发和运维过程中,具 ...

  10. 调试python 程序的几种方法总结

    程序能一次写完并正常运行的概率很小,基本不超过1%.总会有各种各样的bug需要修正.有的bug很简单,看看错误信息就知道,有的bug很复杂,我们需要知道出错时,哪些变量的值是正确的,哪些变量的值是错误 ...