比赛场上很容易想到是费用流,但是没有想到建图方法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. hibernate的拦截器和监听器

    拦截器(Intercept):顾名思义,拦截操作,也就是在Hibernate做出动作之前会调用的方法.如果你有需要在Hibernate操作数据库之前想要做的操作,就需要用到这个东西了. 监听器(Lis ...

  2. Caused by: java.lang.NoClassDefFoundError: javax/validation/ParameterNameProvider

    问题现象:今天部署代码的时候发现,在beta环境可以正常部署,但是到了test环境就一直不成功,我以为是环境问题,就重新部署,但是没效,看了看日志发现问题是:Caused by: java.lang. ...

  3. 【leetcode】993. Cousins in Binary Tree

    题目如下: In a binary tree, the root node is at depth 0, and children of each depth k node are at depth  ...

  4. Security Spring 配置

    <?xml version="1.0" encoding="UTF-8"?><beans:beans xmlns="http://w ...

  5. shell读取文件第一行和最后一行,小数的运算比较

    1. 读取文件的第一行:head -n +1 file.txt 读取文件的最后一行: tail -n -1 file.txt echo 12:30:55 | cut -d: -f 1 结果为12,意思 ...

  6. CDN(Content Delivery Network)内容分发网络

    CDN的全称是Content Delivery Network,即内容分发网络.其基本思路是尽可能避开互联网上有可能影响数据传输速度和稳定性的瓶颈和环节,使内容传输的更快.更稳定.通过在网络各处放置节 ...

  7. angularjs &登录跳转

    如果要使用$location,$stateParams,那么必须有相应形参controller: function ($rootScope, $http, $scope, $state,$locati ...

  8. vue 微信公众号分享后支付失效页面URL不变的坑

    微信分享后支付页面还是初始页面,这个问题解决了, created(){ //判断是否是IOS设备 // IOS分享时的页面是首页,也就是进入页而不是当前页.所有可以采用刷新当前页,让进入页的链接改成当 ...

  9. Android的Context && 安卓常用系统服务(当前运行包名/当前网络状态和开关网络/音频服务/马达服务) (转)

    转:http://blog.csdn.net/zhandoushi1982/article/details/8501773 Context字面意思上下文,位于framework 的android.co ...

  10. js判断是否安装app,安装打开app

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...