比赛场上很容易想到是费用流,但是没有想到建图方法qwq,太弱了。

这里直接贴官方题解:

费用流。离散化坐标,每行用一个点表示,每列也用一个点表示。表示第i-1行的点向表示第i行的点连边,容量为第i行及以后能拿的棋子数的上限,费用为0,同理表示相邻列的点两两连边。若第i行第j列上有棋子,则表示第i行的点向表示第j列的点连边,容量为1,费用为该棋子的价值。可以定义源点表示第0行,汇点表示第0列,源点到汇点的最大费用流即为答案。

就是按照题解的建图方法,还有一些小细节:先要排序排除无用限制来减少限制边数,不然会超时。我用的办法是,按限制从小到大排序,大限制当且仅当它的行数小于小限制行数时才有用。列同理。这里想不明白的建议画图细细想。然后就是连边来表示限制条件:行的话就是(i-1)->i行连边,列的话就是i->(i-1)列连边,这是因为0行是源点0列是汇点所致的,行点要靠它的入边来限制流量,列点要靠出边来限制流量。

细节详见代码及注释:

#include<bits/stdc++.h>
using namespace std;
const int N=+;
const int M=+;
const int INF=0x3f3f3f3f;
int n,m,r,c,s,t,maxflow,mincost;
int nx,ny,x[N],y[N],xx[N],yy[N],bx[N],by[N];
struct edge{
int nxt,to,cap,cost;
}edges[M<<];
int cnt=,head[N],pre[N]; struct dat{ int t,l; } R[M],C[M];
bool cmp(dat a,dat b) { return a.l<b.l || a.l==b.l && a.t<b.t; } void add_edge(int x,int y,int z,int c) {
edges[++cnt].nxt=head[x]; edges[cnt].to=y; edges[cnt].cap=z; edges[cnt].cost=c; head[x]=cnt;
} queue<int> q;
int dis[N],lim[N];
bool inq[N];
bool spfa(int s,int t) {
while (!q.empty()) q.pop();
memset(dis,0x3f,sizeof(dis));
memset(inq,,sizeof(inq));
dis[s]=; inq[s]=; lim[s]=INF; q.push(s);
while (!q.empty()) {
int x=q.front(); q.pop();
for (int i=head[x];i;i=edges[i].nxt) {
edge e=edges[i];
if (e.cap && dis[x]+e.cost<dis[e.to]) {
dis[e.to]=dis[x]+e.cost;
pre[e.to]=i; //即e.to这个点是从i这条边来的
lim[e.to]=min(lim[x],e.cap);
if (!inq[e.to]) { q.push(e.to); inq[e.to]=; }
}
}
inq[x]=;
}
return !(dis[t]==INF);
} void MCMF() {
maxflow=; mincost=;
while (spfa(s,t)) {
int now=t;
maxflow+=lim[t];
mincost+=lim[t]*dis[t];
while (now!=s) {
edges[pre[now]].cap-=lim[t];
edges[pre[now]^].cap+=lim[t];
now=edges[pre[now]^].to;
}
}
} int main()
{
scanf("%d",&n);
for (int i=;i<=n;i++) scanf("%d%d",&x[i],&y[i]),bx[i]=x[i],by[i]=y[i];
nx=ny=n;
scanf("%d",&m);
char opt[];
for (int i=;i<=m;i++) {
int tx,ty; scanf("%s%d%d",opt,&tx,&ty);
if (opt[]=='R') R[++r]=(dat){tx,ty};
if (opt[]=='C') C[++c]=(dat){tx,ty};
}
int tmp=;
sort(R+,R+r+,cmp);
for (int i=;i<=r;i++) //排除行无用限制
if (tmp== || R[i].t<R[tmp].t) R[++tmp]=R[i],bx[++nx]=R[i].t;
r=tmp; tmp=;
sort(C+,C+c+,cmp);
for (int i=;i<=c;i++) //排除列无用限制
if (tmp== || C[i].t<C[tmp].t) C[++tmp]=C[i],by[++ny]=C[i].t;
c=tmp; sort(bx+,bx+nx+); nx=unique(bx+,bx+nx+)-(bx+); //离散化
sort(by+,by+ny+); ny=unique(by+,by+ny+)-(by+); //离散化 for (int i=;i<=n;i++) {
int tx=lower_bound(bx+,bx+nx+,x[i])-bx;
int ty=lower_bound(by+,by+ny+,y[i])-by;
add_edge(tx,nx++ty,,-i); add_edge(nx++ty,tx,,i); //棋子连边
}
memset(xx,0x3f,sizeof(xx));
memset(yy,0x3f,sizeof(yy));
for (int i=;i<=r;i++) {
int tx=lower_bound(bx+,bx+nx+,R[i].t)-bx;
xx[tx]=min(xx[tx],R[i].l); //先求好限制条件,xx[i]代表i行及以后的最小限制
}
for (int i=;i<=c;i++) {
int ty=lower_bound(by+,by+ny+,C[i].t)-by;
yy[ty]=min(yy[ty],C[i].l); //列同行同理
}
//这里是关键:行i-1->i为了限制i的出流,列i->i-1为了限制i的出流
for (int i=;i<=nx;i++) add_edge(i-,i,xx[i],),add_edge(i,i-,,);
for (int i=;i<=ny;i++) add_edge(nx++i,nx++i-,yy[i],),add_edge(nx++i-,nx++i,,); s=; t=nx+;
MCMF();
cout<<-mincost<<endl;
return ;
}

HDU-6532 Chessboard 2019广东省省赛B题(费用流)的更多相关文章

  1. ACM-ICPC 2019南昌网络赛I题 Yukino With Subinterval

    ACM-ICPC 2019南昌网络赛I题 Yukino With Subinterval 题目大意:给一个长度为n,值域为[1, n]的序列{a},要求支持m次操作: 单点修改 1 pos val 询 ...

  2. TI MSP430工程配置及2019年电赛A题编程示例(使用430 F5529)

    配置 第一步:右击工程,选择Options 第二步:在General Options的Target选项卡里选择对应的器件Device,这里是MSP430G2231 第三步:在Debugger里选择FE ...

  3. ACM-ICPC 2019南昌网络赛F题 Megumi With String

    ACM-ICPC 南昌网络赛F题 Megumi With String 题目描述 给一个长度为\(l\)的字符串\(S\),和关于\(x\)的\(k\)次多项式\(G[x]\).当一个字符串\(str ...

  4. 2016青岛区域赛.Coding Contest(费用流 + 概率计算转换为加法计算)

    Coding Contest Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)To ...

  5. Tour HDU - 3488 有向环最小权值覆盖 费用流

    http://acm.hdu.edu.cn/showproblem.php?pid=3488 给一个无源汇的,带有边权的有向图 让你找出一个最小的哈密顿回路 可以用KM算法写,但是费用流也行 思路 1 ...

  6. 2019建模美赛B题(派送无人机)M奖论文

    昨天上午出了建模美赛的结果,我们小组获得的是M奖,感觉挺开心的.我一直觉得拿O奖那种是个概率事件,需要天时地利人和的各种因素都合适才行,所以看到自己是M奖,感觉自己的能力已经得到了认可就很满意了.今天 ...

  7. [2019南京网络赛D题]Robots

    题目链接 2019.9.2更新 第二天睡醒想了想发现好像搜一遍就可以过,赛时写的花里胡哨的还错了,太菜了QAQ #include<bits/stdc++.h> using namespac ...

  8. hdu 4031 2011成都赛区网络赛A题 线段树 ***

    就是不知道时间该怎么处理,想了好久,看了别人的题解发现原来是暴力,暴力也很巧妙啊,想不出来的那种  -_-! #include<cstdio> #include<iostream&g ...

  9. HDU 4119Isabella's Message2011成都现场赛I题(字符串模拟)

    Isabella's Message Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Other ...

随机推荐

  1. Js event对象offsetX,pageX,screenX,clientX详解

       平时在测量元素位置时难以确定,下面给出具体的event对象中的各种属性,以便日后使用.   检测相对于浏览器的位置:clientX和clientY     当鼠标事件发生时,鼠标相对于浏览器左上 ...

  2. mysql基于Altas读写分离并实现高可用

    实验环境准备: master:192.168.200.111 slave1:192.168.200.112 slave2:192.168.200.113 Altas:192.168.200.114 c ...

  3. js 数组、字符串、Json互相转换

    arr.join(): 数组转字符串 let arr = [1,2,3,4]; let str = arr.join(','); arr.split():字符串转数组 let str = '1,2,3 ...

  4. 关于计算机与MCU通信及MAX232、CH340T与PL2303的区别

    原理:单片机的TXD.RXD是TTL电平,所以你得万变不离其宗的将其它信号转成TTL电平,只有这样给单片机下载程序才有可能成功!其中CH340.PL2303等芯片是直接将USB信号转换为TTL电平或者 ...

  5. FTPClient TLS 与 FTP 进行数据传输异常:Remote host closed connection during handshake

    环境:java JDK 1.8.org.apache.commons-net-3.6.jar.端口已放开 FTPClient ftpClient = new FTPClient(protocol, f ...

  6. java中的成员变量、类变量,成员方法、类方法 属性和方法区别

    成员变量:包括实例变量和类变量,用static修饰的是类变量,不用static修饰的是实例变量,所有类的成员变量可以通过this来引用. 类变量:静态域,静态字段,或叫静态变量,它属于该类所有实例共有 ...

  7. 【Flutter学习】之Widget数据共享之InheritedWidget

    一,概述 业务开发中经常会碰到这样的情况,多个Widget需要同步同一份全局数据,比如点赞数.评论数.夜间模式等等.在安卓中,一般的实现方式是观察者模式,需要开发者自行实现并维护观察者的列表.在flu ...

  8. Windows Xp Sp3官方简体中文版(原版) 纯净安装版 百度网盘下载

    百度网盘下载: 1.链接:https://pan.baidu.com/s/1o-HcKddSG6IAz_0COKhq8Q 提取码:hkhr 2.扫码下载:

  9. 性能测试基础 ---TCP通信过程的状态码与过程,以及出现错误码的分析(TIME_WAIT,CLOSE_WAIT)

    TCP通信过程 如下图所示,TCP通信过程包括三个步骤:建立TCP连接通道(三次握手).数据传输.断开TCP连接通道(四次挥手). 这里进一步探究TCP三路握手和四次挥手过程中的状态变迁以及数据传输过 ...

  10. JQuery Mobile 图片布局

    JQuery Mobile 图片布局 1.实现效果