当前位置: 首页 > news >正文

ARC142E Pairing Wizards

ARC142E Pairing Wizards

题目大意

nnn个法师,编号为111nnn。法师iii有强度aia_iai,他计划打败强壮度为bib_ibi的怪物。

你可以执行以下操作任意次:

  • 选中一个法师,将它的强壮度增加1

一对法师(i,j)(i,j)(i,j)称为好的,当至少满足以下条件之一:

  • 法师iii至少有bib_ibi的强壮度,法师jjj至少有bjb_jbj的强壮度
  • 法师iii至少有bjb_jbj的强壮度,法师jjj至少有bib_ibi的强壮度

你的目标是对于i=1,…,mi=1,\dots,mi=1,,m,使得(xi,yi)(x_i,y_i)(xi,yi)称为一对好的法师。求最小的操作数量。


题解

首先,令mnx=max⁡(x,y)∈E(min⁡(bx,by))mn_x=\max\limits_{(x,y)\in E}(\min(b_x,b_y))mnx=(x,y)Emax(min(bx,by))。如果ax<mnxa_x<mn_xax<mnx,则不断增加axa_xax使得ax=mnxa_x=mn_xax=mnx

如果bx>axb_x>a_xbx>ax,则xxx属于XXX集合;如果bx≤axb_x\leq a_xbxax,则xxx属于YYY集合。我们把每一对法师看作一条边,因为上面对axa_xax的改变,所以每条边中至少有一个点在YYY集合中。

每个XXX集合的点xxx对应一个点xxx,每个YYY集合中的点yyy和一个在1到100之间的值aaa对应一个点(y,a)(y,a)(y,a)。我们可以按如下方法建图,那么答案为最小割,即最大流,用网络流即可解决。

  • 对于i∈Xi\in XiX,连边(s,i,bi−ai)(s,i,b_i-a_i)(s,i,biai)
  • 对于i∈Yi\in YiY,连边((i,j),t,1)((i,j),t,1)((i,j),t,1)
  • 对于i∈Yi\in YiY,连边((i,j),(i,j−1),∞)((i,j),(i,j-1),\infty)((i,j),(i,j1),)
  • 对于(i,j)∈E,i∈X,j∈Y,bi>aj(i,j)\in E,i\in X,j\in Y,b_i>a_j(i,j)E,iX,jY,bi>aj,连边(i,(j,bi−aj),∞)(i,(j,b_i-a_j),\infty)(i,(j,biaj),)

如果要使ax≥bxa_x\geq b_xaxbx,则割第一类边;如果要使ax≥by,ay≥bxa_x\geq b_y,a_y\geq b_xaxby,aybx,则割第二类边。因为无限的影响,第三类边只能将jjj值小的放在sss的一边,jjj值大的放在ttt的一边,第四类边不会被割。这样就可以求最小的操作数了。

code

#include<bits/stdc++.h>
using namespace std;
int n,m,x,y,ans=0,vt=0,s,t,v1=0,v2=0,inf=1e9,a[105],b[105],mn[105],on[105],re[105];
int tot=1,cs[100005],l[100005],r[100005],w[100005],d[100005],vd[100005];
struct node{int x,y;
}vw[10005];
void add(int xx,int yy,int zz){l[++tot]=r[xx];cs[tot]=yy;r[xx]=tot;w[tot]=zz;
}
int aug(int i,int augco){if(i==t) return augco;int augc=augco,dl=0,md=n-1;for(int u=r[i];u;u=l[u]){int j=cs[u];if(w[u]>0){if(d[i]==d[j]+1){dl=min(augc,w[u]);dl=aug(j,dl);w[u]-=dl;w[u^1]+=dl;augc-=dl;if(d[s]>=n) return augco-augc;if(!augc) break;}if(md>d[j]) md=d[j];}}if(augco==augc){--vd[d[i]];if(!vd[d[i]]) d[s]=n;d[i]=md+1;++vd[d[i]];}return augco-augc;
}
void sap(){vd[0]=n;while(d[s]<n) ans+=aug(s,inf);
}
int main()
{scanf("%d",&n);s=++vt;t=++vt;for(int i=1;i<=n;i++){scanf("%d%d",&a[i],&b[i]);mn[i]=a[i];}scanf("%d",&m);for(int i=1;i<=m;i++){scanf("%d%d",&x,&y);vw[i]=(node){x,y};mn[x]=max(mn[x],min(b[x],b[y]));mn[y]=max(mn[y],min(b[x],b[y]));}for(int i=1;i<=n;i++){ans+=mn[i]-a[i];a[i]=mn[i];if(a[i]<b[i]){add(s,i+2,b[i]-a[i]);add(i+2,s,0);}else{re[i]=++v2;on[i]=1;for(int j=1;j<=100;j++){add(2+n+(i-1)*100+j,t,1);add(t,2+n+(i-1)*100+j,0);if(j>1){add(2+n+(i-1)*100+j,2+n+(i-1)*100+j-1,inf);add(2+n+(i-1)*100+j-1,2+n+(i-1)*100+j,0);}}}}for(int i=1;i<=m;i++){x=vw[i].x;y=vw[i].y;if(on[x]==0&&on[y]==1){if(b[x]>a[y]){add(x+2,2+n+(y-1)*100+b[x]-a[y],inf);add(2+n+(y-1)*100+b[x]-a[y],x+2,0);}}else if(on[x]==1&&on[y]==0){swap(x,y);if(b[x]>a[y]){add(x+2,2+n+(y-1)*100+b[x]-a[y],inf);add(2+n+(y-1)*100+b[x]-a[y],x+2,0);}}}n=2+n+n*100;sap();printf("%d",ans);return 0;
}
http://www.lryc.cn/news/26539.html

相关文章:

  • Spark开发实战-主播打赏排行榜统计
  • python 如何存储数据 (python 的文件和异常)
  • 第三章-OpenCV基础-8-绘图函数
  • 逆约瑟夫问题
  • MySQL之三大日志(更新中)
  • 如何使用EvilTree在文件中搜索正则或关键字匹配的内容
  • 北京移动CM311-5s-ZG_GK6323V100C_2+8_免拆一键卡刷固件包
  • JavaScript(1)
  • 阿里云云原生每月动态 | 聚焦实战,面向开发者的系列课程全新上线
  • Goby 征文大擂台,超值盲盒等你来!
  • NLP - langid 语种识别
  • liquibase学习和使用
  • redhawk:Low Power Analysis
  • 24- 深度学习的模型保存和加载 (TensorFlow系列) (深度学习)
  • 【Echarts图例点击事件】自定义Echarts图例legend点击事件(已解决)
  • uniapp-首页配置
  • 支持DDR5,超频更简单,小雕够给力,技嘉B760M小雕WIFI主板上手
  • fengMap 自定义dom 偏离实际位置;缩放时飘出地图所在区域
  • TryHackMe-黑我杯
  • 【JAVA程序设计】【C00109】基于SSM(非maven)的员工工资管理系统
  • 《计算机原理》——HelloWorld.cpp如何运行的
  • 【面试题】在JS循环中使用await会怎么样?
  • Qt QMessageBox详解
  • Flutter之beamer路由入门指南
  • 「基础篇」机器学习概览
  • 揭秘可视化图探索工具 NebulaGraph Explore 是如何实现图计算的
  • 移动架构43_什么是Jetpack
  • TiDB的分布式事务原理探究
  • 【C语言】函数指针和指针函数
  • Nodejs中npx简介和作用