题意:棋盘上有n个棋子 每个棋子都有收益

   现在给定1e5条线 有横着的 竖着的

   规定只能在线的一侧选最多ki个棋子

   问最大收益

题解:写自闭的一道题 很容易想到是网络流 但是建图有点难

   第一道最大费用流 居然是边权取反 跑最小费用最大流!

   先离散化坐标 然后可以用点代替一条横线 一条竖线

   如果x,y有一个棋子 就将x所在的横线 向y所在的竖线连一个权值为1 收益为花费的边

   这里要跑最大收益 所以收益要取反

   同时从小到大的每相邻两个横线之间连一条收益为0 边权为x较小的点所受限制条件

   竖线之间也连一条收益为0 边权为y较大的点所受限制条件

   好像越扯越复杂了...  总之就是直接上图吧

   左边表示x = 1, x = 2, x = 3三条线 右边表示y = 1, y = 2 两条线

  

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
int n, m, s, t, cnt, maxflow;
ll mincost;
int cntx, cnty;
int xid[505];
int yid[505];
int kx[505];
int ky[505]; struct po {
int x, y, id;
int tx, ty;
}q[505]; bool cmp1(po A, po B) {return A.x < B.x;}
bool cmp2(po A, po B) {return A.y < B.y;}
bool cmp3(po A, po B) {return A.id < B.id;} int findx(int x) {
if(x <= xid[1]) return 1;
if(x > xid[cntx]) return -1;
int l = 2, r = cntx;
int mid = l + r >> 1;
while(l + 1 < r) {
mid = l + r >> 1;
if(x >= xid[mid]) l = mid;
else r = mid;
}
if(x <= xid[l]) return l;
else return r;
} int findy(int y) {
if(y <= yid[1]) return 1;
if(y > yid[cnty]) return -1;
int l = 2, r = cnty;
int mid = l + r >> 1;
while(l + 1 < r) {
mid = l + r >> 1;
if(y >= yid[mid]) l = mid;
else r = mid;
}
if(y <= yid[l]) return l;
else return r;
} struct node {
int to, nex, val, cost;
}E[100005];
int head[1005];
int cur[1005]; void addedge(int x, int y, int va, int cos) {
E[++cnt].to = y; E[cnt].nex = head[x]; head[x] = cnt; E[cnt].val = va; E[cnt].cost = cos;
E[++cnt].to = x; E[cnt].nex = head[y]; head[y] = cnt; E[cnt].val = 0; E[cnt].cost = -cos;
} int inque[1005];
int dis[1005];
int vis[1005];
bool spfa() {
for(int i = 1; i <= cntx + cnty + 2; i++) inque[i] = 0, dis[i] = INF, cur[i] = head[i];
queue<int> que;
que.push(s);
dis[s] = 0, inque[s] = 1; while(!que.empty()) {
int u = que.front();
que.pop();
inque[u] = 0; for(int i = head[u]; i; i = E[i].nex) {
int v = E[i].to;
if(E[i].val > 0 && dis[v] > dis[u] + E[i].cost) {
dis[v] = dis[u] + E[i].cost;
if(!inque[v]) {
inque[v] = 1;
que.push(v);
}
}
}
}
return dis[t] != INF;
} int dfs(int x, int flow) {
if(x == t) {
vis[t] = 1;
maxflow += flow;
return flow;
} vis[x] = 1;
int used = 0;
int rflow = 0;
for(int i = cur[x]; i; i = E[i].nex) {
cur[x] = i;
int v = E[i].to;
if(E[i].val > 0 && (!vis[v] || v == t) && dis[v] == dis[x] + E[i].cost) {
if(rflow = dfs(v, min(flow - used, E[i].val))) {
used += rflow;
E[i].val -= rflow;
E[i ^ 1].val += rflow;
mincost += 1LL * E[i].cost * rflow;
if(used == flow) break;
}
}
}
return used;
} void dinic() {
maxflow = mincost = 0;
while(spfa()) {
vis[t] = 1;
while(vis[t]) {
memset(vis, 0, sizeof(vis));
dfs(s, INF);
}
}
} int main() { while(~scanf("%d", &n)) {
cnt = 1;
memset(kx, 0, sizeof(kx));
memset(ky, 0, sizeof(ky));
memset(head, 0, sizeof(head));
cntx = cnty = 0;
for(int i = 1; i <= n; i++) scanf("%d%d", &q[i].x, &q[i].y), q[i].id = i;
q[0].x = q[0].y = 0;
sort(q + 1, q + 1 + n, cmp1);
for(int i = 1; i <= n; i++) {
if(q[i].x != q[i - 1].x)
xid[++cntx] = q[i].x;
q[i].tx = cntx;
} sort(q + 1, q + 1 + n, cmp2);
for(int i = 1; i <= n; i++) {
if(q[i].y != q[i - 1].y)
yid[++cnty] = q[i].y;
q[i].ty = cnty;
}
sort(q + 1, q + 1 + n, cmp3); scanf("%d", &m);
for(int i = 1; i <= m; i++) {
getchar();
char a; int b, c;
scanf("%c %d %d", &a, &b, &c);
if(a == 'R') {
int tmp = findx(b);
if(tmp == -1) continue;
if(kx[tmp] == 0) kx[tmp] = c;
else kx[tmp] = min(kx[tmp], c);
} else if(a == 'C') {
int tmp = findy(b);
if(tmp == -1) continue;
if(ky[tmp] == 0) ky[tmp] = c;
else ky[tmp] = min(ky[tmp], c);
}
} s = cntx + cnty + 1;
t = s + 1;
int lasx = n;
for(int i = 1; i <= cntx; i++) {
if(kx[i]) lasx = min(lasx, kx[i]);
if(i == 1) addedge(s, i, lasx, 0);
else addedge(i - 1, i, lasx, 0);
} int lasy = n;
for(int i = 1; i <= cnty; i++) {
if(ky[i]) lasy = min(lasy, ky[i]);
if(i == 1) addedge(cntx + i, t, lasy, 0);
else addedge(cntx + i, cntx + i - 1, lasy, 0);
}
for(int i = 1; i <= n; i++) {
addedge(q[i].tx, q[i].ty + cntx, 1, -q[i].id);
} dinic();
printf("%lld\n", -mincost);
}
return 0;
}

HDU6532 Chessboard (最大费用流)的更多相关文章

  1. HDU-6532 Chessboard 2019广东省省赛B题(费用流)

    比赛场上很容易想到是费用流,但是没有想到建图方法qwq,太弱了. 这里直接贴官方题解: 费用流.离散化坐标,每行用一个点表示,每列也用一个点表示.表示第i-1行的点向表示第i行的点连边,容量为第i行及 ...

  2. hdu-5988 Coding Contest(费用流)

    题目链接: Coding Contest Time Limit: 2000/1000 MS (Java/Others)     Memory Limit: 65536/65536 K (Java/Ot ...

  3. POJ2195 Going Home[费用流|二分图最大权匹配]

    Going Home Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 22088   Accepted: 11155 Desc ...

  4. BZOJ3130: [Sdoi2013]费用流[最大流 实数二分]

    3130: [Sdoi2013]费用流 Time Limit: 10 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 960  Solved: 5 ...

  5. 洛谷 1004 dp或最大费用流

    思路: dp方法: 设dp[i][j][k][l]为两条没有交叉的路径分别走到(i,j)和(k,l)处最大价值. 则转移方程为 dp[i][j][k][l]=max(dp[i-1][j][k-1][l ...

  6. Codeforces 730I [费用流]

    /* 不要低头,不要放弃,不要气馁,不要慌张 题意: 给两行n个数,要求从第一行选取a个数,第二行选取b个数使得这些数加起来和最大. 限制条件是第一行选取了某个数的条件下,第二行不能选取对应位置的数. ...

  7. zkw费用流+当前弧优化

    zkw费用流+当前弧优化 var o,v:..] of boolean; f,s,d,dis:..] of longint; next,p,c,w:..] of longint; i,j,k,l,y, ...

  8. 【BZOJ-4213】贪吃蛇 有上下界的费用流

    4213: 贪吃蛇 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 58  Solved: 24[Submit][Status][Discuss] Desc ...

  9. 【BZOJ-3638&3272&3267&3502】k-Maximum Subsequence Sum 费用流构图 + 线段树手动增广

    3638: Cf172 k-Maximum Subsequence Sum Time Limit: 50 Sec  Memory Limit: 256 MBSubmit: 174  Solved: 9 ...

随机推荐

  1. python基础学习总结

    python管理cisco设备:http://www.linuxeye.com/program/1680.html 学习:https://www.liaoxuefeng.com/wiki/001431 ...

  2. Python运维自动化psutil 模块详解(超级详细)

    psutil 模块 参考官方文档:https://pypi.org/project/psutil/ 一.psutil简介 psutil是一个开源且跨平台(http://code.google.com/ ...

  3. zabbix的汉化

    1.在windows中找一个自己喜欢的字体(C:\Windows\Fonts)或者去网上下载一个 2.将字体上传到zabbix的web相关目录的fonts目录下 (我的zabbix的web相关的文件都 ...

  4. 【Linux】ntp的一些坑。你肯定遇到过

    ntpdate提示 19 Jan 10:33:11 ntpdate[29616]: no server suitable for synchronization found 这种问题从下面几个点开始验 ...

  5. P2327 [SCOI2005]扫雷(递推)

    题目链接: https://www.luogu.org/problemnew/show/P2327 题目描述 相信大家都玩过扫雷的游戏.那是在一个$n*m$的矩阵里面有一些雷,要你根据一些信息找出雷来 ...

  6. 深入理解Redis之简单动态字符串

    目录 SDS SDS与C字符串的区别 SDS获取字符串长度复杂度为O(1),C字符串为O(N) SDS杜绝了缓存区溢出 减少修改字符串时带来的内存重分配次数 二进制安全 Redis没有直接使用C语言传 ...

  7. 如何实现微信小程序动画?添加到我的小程序动画实现详细讲解,轻松学会动画开发!附壁纸小程序源码下载链接

    为了让用户能尽可能多地使用小程序,也算是沉淀用户,现在很多小程序中,都有引导用户"添加到我的小程序"的操作提示,而且大多都是有动画效果.在高清壁纸推荐小程序首页,用户每次进入,都会 ...

  8. Android 中使用 config.gradle

    各位同学大家好,当然了如果不是同学,那么大家也同好.哈哈. 大家知道config.gradle 是什么吗?我也不知道.开个完笑,其实config.gradle 就是我们为了统一gradle 中的各种配 ...

  9. [Poi2005]Piggy Banks小猪存钱罐

    题目描述 Byteazar有 N 个小猪存钱罐. 每个存钱罐只能用钥匙打开或者砸开. Byteazar已经把每个存钱罐的钥匙放到了某些存钱罐里. Byteazar 现在想买一台汽车于是要把所有的钱都取 ...

  10. MYSQL(将数据加载到表中)

    1. 创建和选择数据库 mysql> CREATE DATABASE menagerie; mysql> USE menagerie Database changed 2. 创建表 mys ...