如果一个红石头在另一个红石头的左下方(包括左和下),那么在后者的限制满足时,前者也一定满足,因此可以删去前者,再将其按照$rx_{i}$排序,即有$rx_{1}<rx_{2}<...<rx_{n}$且$ry_{1}>ry_{2}>...>ry_{n}$

称一个蓝石头覆盖一个红石头当且今当后者在前者的左下方(包括左和下),若一个蓝石头在$(x,y)$,要使其覆盖区间$[l,r]$的红石头,所需代价即$\max(rx_{r}-x,0)+\max(ry_{l}-y,0)$

下面,来考虑$k=1$的情况:

对于一个蓝石头,注意到覆盖$[l_{1},r_{1}]$和$[l_{2},r_{2}]$的代价不小于覆盖$[l_{1},r_{2}]$的代价(其中$l_{1}\le r_{1}<l_{2}\le r_{2}$),因此我们不妨允许其重复使用

由此,令$f_{i}$表示前$i$个红石头都被覆盖的最小代价,枚举上一段被覆盖的区间,即有转移
$$
f_{i}=\min_{1\le j\le i}(f_{j-1}+\min_{1\le l\le m}(\max(rx_{i}-bx_{l},0)+\max(ry_{j}-by_{l},0)))
$$
关于这个dp,可以建立下述有向图来解决——

将每一个石头拆为两个节点,分别称为$x$坐标的节点和$y$坐标的节点

将所有$x$坐标的节点按$x$坐标从小到大排序,每一个节点向下一个节点连边权为两者$x$坐标差值的边,向上一个节点连边权为0的边

将所有$y$坐标的节点按$y$坐标从大到小排序,并与$x$坐标类似的连边

将所有蓝石头$y$坐标的节点向$x$坐标的节点连边权为0的边

此时,第$j$个红石头$y$坐标的节点到第$i$个红石头$x$坐标的节点的最短路即为
$$
\min_{1\le l\le m}(\max(rx_{i}-bx_{l},0)+\max(ry_{j}-by_{l},0))
$$
(这里也允许红石头向红石头移动和蓝石头向蓝石头移动,但这类边实际上一定不优)

将第$i$个红石头$x$坐标的节点向第$i+1$个红石头$y$坐标的节点连边权为0的边,那么第1个红石头$y$坐标的节点到第$n$个红石头$x$坐标的节点的最短路即为答案

接下来,对于任意$k$的情况,实际上即在这张图中找到$k$条路径,且其中蓝石头$x$和$y$坐标的节点之间的连边只能被使用一次,最小化这$k$条路径的长度和

显然这可以用网络流解决,即在此图的基础上,每条边的流量为无穷大(但蓝石头$x$和$y$坐标的节点之间的连边流量为1)且费用为边权,最终求流量为$k$的最小费用即为答案

通过费用流的做法,即做$k$次增广,每一次增广是spfa,复杂度为$o(kn^{2})$,无法通过

给每一个节点一个势能$h_{i}$,再将一条边的费用由$w$变为$w+h_{x}-h_{y}$,那么对于一条从$x$到$y$的路径,实际上即在原费用的基础上再加$h_{x}-h_{y}$,这显然不影响$x$到$y$的最短路

换言之,我们只需要找到合适的$h_{i}$,使得(对于流量非0的边)$w+h_{x}-h_{y}$都非负,那么以$w+h_{x}-h_{y}$为费用求最短路,就可以使用dijkstra,复杂度即降为$o(kn\log n)$

初始由于没有负权(负权边都是反向边,流量为0),直接令$h_{i}=0$即可

接下来每一次求完最短路后增广,会导致一些边流量由0变为非0,因此要调整$h_{i}$

具体的,设最短路为$d_{i}$,只需要令$h'_{i}=h_{i}+d_{i}$即可,下面来证明$w+h'_{x}-h'_{y}\ge 0$:

若$(x,y)$在增广前流量非0,那么$d_{y}\le d_{x}+(w+h_{x}-h_{y})$,化简后即可得$w+h'_{x}-h'_{y}\ge 0$

若$(x,y)$在增广前流量为0且增广后流量非0,即$(y,x)$被作为最短路,也即$d_{y}=d_{x}+(-w+h_{x}-h_{y})$(根据费用流的建边,$(x,y)$和$(y,x)$的费用互为相反数),化简后即可得$w+h'_{x}-h'_{y}=0$

综上,总时间复杂度为$o(kn\log n)$,可以通过

  1. 1 #include<bits/stdc++.h>
  2. 2 using namespace std;
  3. 3 #define N 400005
  4. 4 #define ll long long
  5. 5 #define fi first
  6. 6 #define se second
  7. 7 struct Edge{
  8. 8 int nex,to,len,cost;
  9. 9 }edge[N*6];
  10. 10 pair<int,int>a[N];
  11. 11 vector<pair<int,int> >vx,vy;
  12. 12 priority_queue<pair<ll,int> >q;
  13. 13 int E,S,T,n,m,k,x,y,head[N],vis[N],from[N];
  14. 14 ll h[N],d[N];
  15. 15 void add(int x,int y,int z,int w){
  16. 16 edge[E].nex=head[x];
  17. 17 edge[E].to=y;
  18. 18 edge[E].len=z;
  19. 19 edge[E].cost=w;
  20. 20 head[x]=E++;
  21. 21 if (E&1)add(y,x,0,-w);
  22. 22 }
  23. 23 bool dijkstra(){
  24. 24 memset(d,0x3f,sizeof(d));
  25. 25 memset(vis,0,sizeof(vis));
  26. 26 d[S]=0;
  27. 27 q.push(make_pair(0,S));
  28. 28 while (!q.empty()){
  29. 29 int k=q.top().second;
  30. 30 q.pop();
  31. 31 if (vis[k])continue;
  32. 32 vis[k]=1;
  33. 33 for(int i=head[k];i!=-1;i=edge[i].nex){
  34. 34 ll c=edge[i].cost+h[k]-h[edge[i].to];
  35. 35 if ((edge[i].len)&&(d[edge[i].to]>d[k]+c)){
  36. 36 d[edge[i].to]=d[k]+c;
  37. 37 from[edge[i].to]=i;
  38. 38 q.push(make_pair(-d[edge[i].to],edge[i].to));
  39. 39 }
  40. 40 }
  41. 41 }
  42. 42 return d[T]!=d[0];
  43. 43 }
  44. 44 ll dinic(){
  45. 45 ll ans=0;
  46. 46 for(int i=1;i<=k;i++){
  47. 47 dijkstra();
  48. 48 ans+=d[T]-(h[S]-h[T]);
  49. 49 for(int i=T;i!=S;i=edge[from[i]^1].to){
  50. 50 edge[from[i]].len--;
  51. 51 edge[from[i]^1].len++;
  52. 52 }
  53. 53 for(int i=1;i<=2*(n+m);i++)h[i]+=d[i];
  54. 54 }
  55. 55 return ans;
  56. 56 }
  57. 57 int main(){
  58. 58 scanf("%d%d%d",&n,&m,&k);
  59. 59 memset(head,-1,sizeof(head));
  60. 60 for(int i=1;i<=n;i++){
  61. 61 scanf("%d%d",&x,&y);
  62. 62 a[i]=make_pair(x,y);
  63. 63 }
  64. 64 sort(a+1,a+n+1);
  65. 65 int mx=-1,nn=0;
  66. 66 for(int i=n;i;i--){
  67. 67 if (a[i].se<=mx)vis[i]=1;
  68. 68 else{
  69. 69 mx=a[i].se;
  70. 70 nn++;
  71. 71 }
  72. 72 }
  73. 73 for(int i=1,j=0;i<=n;i++)
  74. 74 if (!vis[i]){
  75. 75 j++;;
  76. 76 vx.push_back(make_pair(a[i].fi,j));
  77. 77 vy.push_back(make_pair(a[i].se,j+nn+m));
  78. 78 if (j<nn)add(j,j+1+nn+m,k,0);
  79. 79 }
  80. 80 n=nn;
  81. 81 for(int i=1;i<=m;i++){
  82. 82 scanf("%d%d",&x,&y);
  83. 83 vx.push_back(make_pair(x,i+n));
  84. 84 vy.push_back(make_pair(y,i+n+n+m));
  85. 85 add(i+n+n+m,i+n,1,0);
  86. 86 }
  87. 87 sort(vx.begin(),vx.end());
  88. 88 sort(vy.begin(),vy.end());
  89. 89 for(int i=1;i<vx.size();i++){
  90. 90 add(vx[i-1].se,vx[i].se,k,vx[i].fi-vx[i-1].fi);
  91. 91 add(vx[i].se,vx[i-1].se,k,0);
  92. 92 }
  93. 93 for(int i=1;i<vy.size();i++){
  94. 94 add(vy[i].se,vy[i-1].se,k,vy[i].fi-vy[i-1].fi);
  95. 95 add(vy[i-1].se,vy[i].se,k,0);
  96. 96 }
  97. 97 S=1+n+m,T=n;
  98. 98 printf("%lld",dinic());
  99. 99 }

[atARC122F]Domination的更多相关文章

  1. 2014牡丹江D Domination

    Domination Time Limit: 8 Seconds      Memory Limit: 131072 KB      Special Judge Edward is the headm ...

  2. zoj3822 Domination(概率dp)

    Domination Time Limit: 8 Seconds      Memory Limit: 131072 KB      Special Judge Edward is the headm ...

  3. ZOJ 3822 Domination 期望dp

    Domination Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.zju.edu.cn/onlinejudge/showProblem ...

  4. zoj 3822 Domination (可能性DP)

    Domination Time Limit: 8 Seconds      Memory Limit: 131072 KB      Special Judge Edward is the headm ...

  5. zoj 3822 Domination(2014牡丹江区域赛D称号)

    Domination Time Limit: 8 Seconds      Memory Limit: 131072 KB      Special Judge Edward is the headm ...

  6. ZOJ3822 ACM-ICPC 2014 亚洲杯赛事现场牡丹江司D称号Domination 可能性DP

    Domination Time Limit: 8 Seconds      Memory Limit: 131072 KB      Special Judge Edward is the headm ...

  7. zoj 3822 Domination(dp)

    题目链接:zoj 3822 Domination 题目大意:给定一个N∗M的棋盘,每次任选一个位置放置一枚棋子,直到每行每列上都至少有一枚棋子,问放置棋子个数的期望. 解题思路:大白书上概率那一张有一 ...

  8. Domination(概率DP)

    Domination 题目链接:https://odzkskevi.qnssl.com/9713ae1d3ff2cc043442f25e9a86814c?v=1531624384 Edward is ...

  9. ZOJ 3822 Domination 概率dp 难度:0

    Domination Time Limit: 8 Seconds      Memory Limit: 131072 KB      Special Judge Edward is the headm ...

随机推荐

  1. 数值分析:幂迭代和PageRank算法

    1. 幂迭代算法(简称幂法) (1) 占优特征值和占优特征向量 已知方阵\(\bm{A} \in \R^{n \times n}\), \(\bm{A}\)的占优特征值是量级比\(\bm{A}\)所有 ...

  2. Conversion Tools(转换工具)

    转换工具 1.Excel # Process: Excel 转表 arcpy.ExcelToTable_conversion("", 输出表, "") # Pr ...

  3. MS office设置夜间模式

    点击文件 帐户 -> office主题

  4. ❤️【Python从入门到精通】(二十七)更进一步的了解Pillow吧!

    您好,我是码农飞哥,感谢您阅读本文,欢迎一键三连哦. 进一步介绍Pillow库的使用,详细了解 干货满满,建议收藏,需要用到时常看看. 小伙伴们如有问题及需要,欢迎踊跃留言哦~ ~ ~. 前言 本文是 ...

  5. PG集群(PostgreSql环境)搭建

    centos PG集群搭建 一.安装PG 1.安装之前首先查看软件是否已经安装 rpm -qa | grep postgresql #若存在,需要卸载使用 yum remove postgresql ...

  6. docker内服务访问宿主机服务

    目录 1. 场景 2. 解决 4. 参考 1. 场景 使用windows, wsl2 进行日常开发测试工作. 但是wsl2经常会遇到网络问题.比如今天在测试一个项目,核心功能是将postgres 的数 ...

  7. 力扣 - 剑指 Offer 53 - II. 0~n-1中缺失的数字

    题目 剑指 Offer 53 - II. 0-n-1中缺失的数字 思路1 排序数组找数字使用二分法 通过题目,我们可以得到一个规律: 如果数组的索引值和该位置的值相等,说明还未缺失数字 一旦不相等了, ...

  8. 康托展开+逆展开(Cantor expension)详解+优化

    康托展开 引入 康托展开(Cantor expansion)用于将排列转换为字典序的索引(逆展开则相反) 百度百科 维基百科 方法 假设我们要求排列 5 2 4 1 3 的字典序索引 逐位处理: 第一 ...

  9. Java:static关键字小记

    Java:static关键字小记 对 Java 中的 static 关键字,做一个微不足道的小小小小记 static 修饰变量 静态变量:是被 static 修饰的变量,也称为类变量,它属于类,因此不 ...

  10. Spring动态添加定时任务

    Spring动态添加定时任务 一.背景 二.需求和实现思路 1.能够动态的添加一个定时任务. 2.能够取消定时任务的执行. 3.动态的修改任务执行的时间. 4.获取定时任务执行的异常 三.代码实现 四 ...