用到了二分图的一些性质, 最大匹配数=最小点覆盖

貌似在白书上有讲

还不是很懂, 自己看着别人的博客用网络流写了一遍

反正以后学白书应该会系统学二分图的,紫书上没讲深。

目前就这样吧。

#include<cstdio>
#include<vector>
#include<cstring>
#include<queue>
#include<algorithm>
#define REP(i, a, b) for(int i = (a); i < (b); i++)
using namespace std; const int MAXN = 21234;
const int MAXM = 112;
struct Edge{ int from, to, cap, flow; };
vector<Edge> edges;
vector<int> g[MAXN];
int cur[MAXN], h[MAXN];
int n, m, s, t;
int map[MAXM][MAXM], c[MAXM][MAXM], r[MAXM][MAXM]; void AddEdge(int from, int to, int cap)
{
edges.push_back(Edge{from, to, cap, 0});
edges.push_back(Edge{to, from, 0, 0});
g[from].push_back(edges.size() - 2);
g[to].push_back(edges.size() - 1);
} bool bfs()
{
queue<int> q;
q.push(s);
memset(h, 0, sizeof(h));
h[s] = 1; while(!q.empty())
{
int x = q.front(); q.pop();
REP(i, 0, g[x].size())
{
Edge& e = edges[g[x][i]];
if(e.cap > e.flow && !h[e.to])
{
h[e.to] = h[x] + 1;
q.push(e.to);
}
}
} return h[t];
} int dfs(int x, int a)
{
if(x == t || a == 0) return a;
int flow = 0, f;
for(int& i = cur[x]; i < g[x].size(); i++)
{
Edge& e = edges[g[x][i]];
if(h[x] + 1 == h[e.to] && (f = dfs(e.to, min(a, e.cap - e.flow))) > 0)
{
e.flow += f;
edges[g[x][i] ^ 1].flow -= f;
flow += f;
if((a -= f) == 0) break;
}
}
return flow;
} int maxflow()
{
int flow = 0;
while(bfs())
{
memset(cur, 0, sizeof(cur));
flow += dfs(s, 1e9);
}
return flow;
} void make_edges()
{
int cnt = 0, tmp;
REP(i, 0, n)
{
bool ok = true;
REP(j, 0, m)
{
if(map[i][j] == 1)
{
if(ok) cnt++;
r[i][j] = cnt;
ok = false;
}
else if(map[i][j] == 2) ok = true;
}
}
tmp = cnt; REP(j, 0, m)
{
bool ok = true;
REP(i, 0, n)
{
if(map[i][j] == 1)
{
if(ok) cnt++;
c[i][j] = cnt;
ok = false;
}
else if(map[i][j] == 2) ok = true;
}
} REP(i, 1, cnt + 5) g[i].clear();
s = cnt + 3, t = s + 1;
REP(i, 1, tmp + 1) AddEdge(s, i, 1);
REP(i, tmp + 1, cnt + 1) AddEdge(i, t, 1);
REP(i, 0, n)
REP(j, 0, m)
if(map[i][j] == 1)
AddEdge(r[i][j], c[i][j], 1);
} int main()
{
int T;
scanf("%d", &T); while(T--)
{
scanf("%d%d", &n, &m);
edges.clear();
memset(map, 0, sizeof(map));
memset(c, 0, sizeof(c));
memset(r, 0, sizeof(r)); int tmp, x, y;
scanf("%d", &tmp);
while(tmp--)
{
scanf("%d%d", &x, &y);
x--; y--;
map[x][y] = 1;
}
scanf("%d", &tmp);
while(tmp--)
{
scanf("%d%d", &x, &y);
x--; y--;
map[x][y] = 2;
} make_edges();
printf("%d\n", maxflow());
} return 0;
}

紫书 习题 11-9 UVa 12549 (二分图最小点覆盖)的更多相关文章

  1. 四川第七届 D Vertex Cover(二分图最小点覆盖,二分匹配模板)

    Vertex Cover frog has a graph with nn vertices v(1),v(2),…,v(n)v(1),v(2),…,v(n) and mm edges (v(a1), ...

  2. POJ2226 Muddy Fields(二分图最小点覆盖集)

    题目给张R×C的地图,地图上*表示泥地..表示草地,问最少要几块宽1长任意木板才能盖住所有泥地,木板可以重合但不能盖住草地. 把所有行和列连续的泥地(可以放一块木板铺满的)看作点且行和列连续泥地分别作 ...

  3. POJ1325 Machine Schedule(二分图最小点覆盖集)

    最小点覆盖集就是在一个有向图中选出最少的点集,使其覆盖所有的边. 二分图最小点覆盖集=二分图最大匹配(二分图最大边独立集) 这题A机器的n种模式作为X部的点,B机器的m种模式作为Y部的点: 每个任务就 ...

  4. hihoCoder #1127:二分图最小点覆盖和最大独立集

    题目大意:求二分图最小点覆盖和最大独立集. 题目分析:如果选中一个点,那么与这个点相连的所有边都被覆盖,使所有边都被覆盖的最小点集称为最小点覆盖,它等于最大匹配:任意两个点之间都没有边相连的最大点集称 ...

  5. [POJ] 2226 Muddy Fields(二分图最小点覆盖)

    题目地址:http://poj.org/problem?id=2226 二分图的题目关键在于建图.因为“*”的地方只有两种木板覆盖方式:水平或竖直,所以运用这种方式进行二分.首先按行排列,算出每个&q ...

  6. 二分图 最小点覆盖 poj 3041

    题目链接:Asteroids - POJ 3041 - Virtual Judge  https://vjudge.net/problem/POJ-3041 第一行输入一个n和一个m表示在n*n的网格 ...

  7. HihoCoder1127 二分图三·二分图最小点覆盖和最大独立集

    二分图三·二分图最小点覆盖和最大独立集 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 在上次安排完相亲之后又过了挺长时间,大家好像都差不多见过面了.不过相亲这个事不是说 ...

  8. hihoCoder #1127 : 二分图二·二分图最小点覆盖和最大独立集

    #1127 : 二分图二·二分图最小点覆盖和最大独立集 Time Limit:10000ms Case Time Limit:1000ms Memory Limit:256MB 描述 在上次安排完相亲 ...

  9. Asteroids POJ - 3041 二分图最小点覆盖

       Asteroids POJ - 3041 Bessie wants to navigate her spaceship through a dangerous asteroid field in ...

  10. UVA1194 Machine Schedule[二分图最小点覆盖]

    题意翻译 有两台机器 A,B 分别有 n,m 种模式. 现在有 k 个任务.对于每个任务 i ,给定两个整数$ a_i\(和\) b_i$,表示如果该任务在 A上执行,需要设置模式为 \(a_i\): ...

随机推荐

  1. JVM 原理

    0 引言  JVM一直是java知识里面进阶阶段的重要部分,如果希望在java领域研究的更深入,则JVM则是如论如何也避开不了的话题,本系列试图通过简洁易读的方式,讲解JVM必要的知识点. 1 运行流 ...

  2. node——由新闻列表跳转到新闻详情页

    当我们在浏览新闻列表页面的时候,想要看感兴趣的新闻内容,需要到详情页面去查看内容. 在之前写好了新闻列表页面,现在需要做列表页面到详情页面的跳转,需要考虑一下问题 1.点击新闻列表某一项跳转到详情页面 ...

  3. python3配置爬虫开发环境

    爬虫:环境搭建 安装python3: 安装python版本:3.7.0 winsdows下的配置:

  4. shell脚本杀死某个服务的进程

    摘抄如下: 新建sh结尾的文件内容如下: NAME=$1echo $NAMEID=`ps -ef | grep "$NAME" | grep -v "$0" | ...

  5. 归档 SCP SFTP RSYNC(数据同步)

    tar 选项  目标文件  源文件(1 2 3) tar cf **.tar file1 file2 file3 (默认情况下 cf选项只有归档没有压缩) tar xf 从归档中提取 创建tar的存档 ...

  6. Lvs+heartbeat高可用高性能web站点的搭建

    这是我们公司在实际的生产环境当中使用的一套东西,希望对大家有所帮助(实际的公网ip,我已经做了相应的修改): 说明:每台服务器需要有两块网卡:eth0连接内网的交换机,用私网ip,实现服务器间内部访问 ...

  7. MyBatis学习总结(8)——Mybatis3.x与Spring4.x整合

    一.搭建开发环境 1.1.使用Maven创建Web项目 执行如下命令: mvn archetype:create -DgroupId=me.gacl -DartifactId=spring4-myba ...

  8. DQL命令(查询)

     select *或字段1,字段2...     from 表名     [where 条件]       提示:*符号表示取表中所有列:没有where语句表示        查询表中所有记录:有wh ...

  9. HDU 4240 Route Redundancy

    Route Redundancy Time Limit: 1000ms Memory Limit: 32768KB This problem will be judged on HDU. Origin ...

  10. 五大最佳开源java性能监控工具

    如果你正在寻找性能监控工具,不妨看看以下推荐的这五款开源工具,这些工具目前已经可以替代付费工具了,你可以看看是否是你的最佳选择.本文推荐的五款开源工具目前是开源社区中最受欢迎的. 1. Stagemo ...