Codeforces 1198E Rectangle Painting 2 最小点覆盖(网络流)
题意:有一个n * n的棋盘,每个棋盘有某些矩形区域被染成了黑色(这些矩形区域有可能相交),问把所有黑色区域染成白色的最小花费是多少?你每次可以选择把一个矩形区域染成白色,花费是染色的矩形区域长和宽的最小值。
思路:容易发现,假设一个矩形的坐标是(l1, r1, l2, r2),假设(l2 - l1 < r2 - r1), 那么我们把r1和r2变成1和n对答案不会有影响。那么,我们发现问题转化为了选最少的行和列使得所有的黑色区域被覆盖,换句话说,就是所有的点至少被一个行货列所覆盖。我们把行看成左边的点,列看成右边的点,黑色的点看成边,那么这个问题就变成了求二分图的最小点覆盖。但是直接用二分图做边数点数会很大,所有我们可以离散化之后变成求网络流的最大流。
代码:
- #include <bits/stdc++.h>
- #define pii pair<int, int>
- #define LL long long
- #define INF 1e18
- using namespace std;
- const int maxm = 100100;
- const int maxn = 510;
- bool v[310][310];
- int head[maxn], Next[maxm * 6], ver[maxm * 6], tot = 1;
- int d[maxn], s ,t;
- LL edge[maxm * 6];
- void add(int x, int y, LL z) {
- ver[++tot] = y, edge[tot] = z, Next[tot] = head[x], head[x] = tot;
- ver[++tot] = x, edge[tot] = 0, Next[tot] = head[y], head[y] = tot;
- }
- queue<int> q;
- bool bfs() {
- memset(d, 0, sizeof(d));
- while(q.size()) q.pop();
- q.push(s), d[s] = 1;
- while(q.size()) {
- int x = q.front();
- q.pop();
- for (int i = head[x]; i; i = Next[i]) {
- if(edge[i] && !d[ver[i]]) {
- q.push(ver[i]);
- d[ver[i]] = d[x] + 1;
- if(ver[i] == t) return 1;
- }
- }
- }
- return 0;
- }
- LL dinic(int x, LL flow) {
- if(x == t) return flow;
- LL rest = flow, k;
- for (int i = head[x]; i && rest; i = Next[i]) {
- if(edge[i] && d[ver[i]] == d[x] + 1) {
- k = dinic(ver[i], min(rest, edge[i]));
- if(!k) d[ver[i]] = 0;
- edge[i] -= k;
- edge[i ^ 1] += k;
- rest -= k;
- }
- }
- return flow - rest;
- }
- vector<int> X, Y;
- vector<pii> L, R;
- int main() {
- int n, m, l1, r1, l2, r2, sz;
- scanf("%d%d", &n, &m);
- X.push_back(0), X.push_back(n);
- Y.push_back(0), Y.push_back(n);
- for (int i = 1; i <= m; i++) {
- scanf("%d%d%d%d", &l1, &r1, &l2, &r2);
- l1--, r1--;
- L.push_back(make_pair(l1, r1));
- R.push_back(make_pair(l2, r2));
- X.push_back(l1), X.push_back(l2);
- Y.push_back(r1), Y.push_back(r2);
- }
- sort(X.begin(), X.end());
- sort(Y.begin(), Y.end());
- sz = unique(X.begin(), X.end()) - X.begin();
- while(X.size() > sz) X.pop_back();
- sz = unique(Y.begin(), Y.end()) - Y.begin();
- while(Y.size() > sz) Y.pop_back();
- s = 210, t = 211;
- for (int i = 0; i < X.size() - 1; i++) {
- add(s, i, X[i + 1] - X[i]);
- }
- for (int i = 0; i < Y.size() - 1; i++) {
- add(i + X.size(), t, Y[i + 1] - Y[i]);
- }
- for (int i = 0; i < m; i++) {
- l1 = lower_bound(X.begin(), X.end(), L[i].first) - X.begin();
- r1 = lower_bound(Y.begin(), Y.end(), L[i].second) - Y.begin();
- l2 = lower_bound(X.begin(), X.end(), R[i].first) - X.begin();
- r2 = lower_bound(Y.begin(), Y.end(), R[i].second) - Y.begin();
- for (int i = l1; i < l2; i++) {
- for (int j = r1; j < r2; j++) {
- v[i][j] = 1;
- }
- }
- }
- for (int i = 0; i < X.size() - 1; i++) {
- for (int j = 0; j < Y.size() - 1; j++) {
- if(v[i][j]) {
- add(i, j + X.size(), INF);
- }
- }
- }
- LL flow = 0, maxflow = 0;
- while(bfs())
- while(flow = dinic(s, INF)) maxflow += flow;
- printf("%lld\n", maxflow);
- }
Codeforces 1198E Rectangle Painting 2 最小点覆盖(网络流)的更多相关文章
- codeforces 1198E Rectangle Painting 2 最小点覆盖
题目传送门 题意: 有一个$n∗n$的网格,网格中有一些矩形是黑的,其他点都是白的. 你每次可以花费$ min (h,w)$的代价把一个$h*w$的矩形区域变白.求把所有黑格变白的最小代价. 思路: ...
- Codeforces - 1198D - Rectangle Painting 1 - dp
https://codeforces.com/contest/1198/problem/D 原来是dp的思路,而且是每次切成两半向下递归.好像在哪里见过类似的,貌似是紫书的样子. 再想想好像就很显然的 ...
- Codeforces #576 Rectangle Painting 1 | div1D | div2F | DP | Rustlang
原题链接 大意 n*n正方形 有黑有白 每次可以选择一个 矩形把它全变成白色,代价是max(长,宽) 求吧 整个正方形 全变白 的最小代价 数据范围 n <= 50 题解 首先如果 我们刷了两个 ...
- Jewelry Exhibition(最小点覆盖集)
Jewelry Exhibition 时间限制: 1 Sec 内存限制: 64 MB提交: 3 解决: 3[提交][状态][讨论版] 题目描述 To guard the art jewelry e ...
- 紫书 习题 11-9 UVa 12549 (二分图最小点覆盖)
用到了二分图的一些性质, 最大匹配数=最小点覆盖 貌似在白书上有讲 还不是很懂, 自己看着别人的博客用网络流写了一遍 反正以后学白书应该会系统学二分图的,紫书上没讲深. 目前就这样吧. #includ ...
- Cogs 1632. 搬运工(二分图最小点覆盖)
搬运工 ★ 输入文件:worker.in 输出文件:worker.out 简单对比 时间限制:1 s 内存限制:256 MB [题目描述] 小涵向小宇推荐了一款小游戏. 游戏是这样的,在一个n*n的地 ...
- Strategic game(无向?)二分图最小点覆盖(Poj1463,Uva1292)
原题链接 此题求二分图的最小点覆盖,数值上等于该二分图的最大匹配.得知此结论可以将图染色,建有向图,然后跑匈牙利/网络流,如下.然而... #include<iostream> #incl ...
- ACM/ICPC 之 机器调度-匈牙利算法解最小点覆盖集(DFS)(POJ1325)
//匈牙利算法-DFS //求最小点覆盖集 == 求最大匹配 //Time:0Ms Memory:208K #include<iostream> #include<cstring&g ...
- 【POJ 3041】Asteroids (最小点覆盖)
每次选择清除一行或者一列上的小行星.最少选择几次. 将行和列抽象成点,第i行为节点i+n,第j列为节点j,每个行星则是一条边,连接了所在的行列. 于是问题转化成最小点覆盖.二分图的最小点覆盖==最大匹 ...
随机推荐
- [前端自动化]grunt的简单使用
前言 现在前端自动化已经是家常便饭,各种工具也是层出不穷,grunt.gulp.webpack是应用最广的三种工具,虽然grunt看似已垂垂老矣,但是以前写的很多项目一直用的就是grunt,温故方能知 ...
- mysql 联合表查询从表即使有索引依然ALL的一个原因
那就是主表和从表的关联字段的编码方式不一样!!! 晕啊,折腾了半天才发现,可能是不知道啥时候mysql更改主体编码方式了,结果导致后来新建的表的关联字段和之前的主表的字段的编码方式不一样 改成一样的编 ...
- svnkit 异常:Exception in thread "main" org.tmatesoft.svn.core.SVNException: svn: E200030: SQLite error
https://stackoverflow.com/questions/16063105/org-tmatesoft-sqljet-core-sqljetexception-busy-error-co ...
- ftp 上传文件时报 cant open output connection for file "ftp://129.28.149.240/shop/web/index.html". Reason: "550 Permission denied.".
原因:没有写入权限 修改权限即可 vsftpd.conf vim /etc/vsftpd.conf write_enable=YES #加入这句
- 使用字节流(InputStream、OutputStream)简单完成对文件的复制
文件的复制 import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; imp ...
- uwsgi部署django项目
一.更新系统软件包 yum update -y 二.安装软件管理包及依赖 yum -y groupinstall "Development tools" yum install o ...
- 英语单词Permissive
Permissive 来源 [root@centos7 ~]# setenforce usage: setenforce [ Enforcing | Permissive | | ] 翻译 adj. ...
- 源码分析笔记Vector
概述 继承抽象类AbStractList,实现接口List.RandomAccess.Cloneable以及序列化接口默认容量大小为10,扩容增量为0,扩容为原容量的2倍如设置的增量大于0,则扩容为( ...
- SPRING CLOUD微服务DEMO-下篇
目录 1 Hystix 1.1 简介 1.2 配置并测试 2. Feign 2.1 简介 2.2 使用Feign 2.3 负载均衡 2.4 Hystrix支持 2.5.请求压缩 3. Zuul网关 3 ...
- Websphere如何查看后台的日志以及简单应用
文章目录 查找日志 简单应用: 安装应用 查找日志 /opt/IBM/WebSphere/AppServer/profiles/default/logs/server1/SystemOut.log 这 ...