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

貌似在白书上有讲

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

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

目前就这样吧。

#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. 改变浏览器页面默认滚动条样式scrollbar

    scrollbar-3d-light-color 设置或检索滚动条亮边框颜色scrollbar-highlight-color 设置或检索滚动条3D界面的亮边(ThreedHighlight)颜色sc ...

  2. 2、使用Python3爬取美女图片-网站中的妹子自拍一栏

    代码还有待优化,不过目的已经达到了 1.先执行如下代码: #!/usr/bin/env python #-*- coding: utf-8 -*- import urllib import reque ...

  3. 2019-03-19 SQL Server简单存储过程的创建 删除 执行

    --创建名为 Get 的有输入参数的存储过程 create proc Get --设置默认值 @TrustId int ='001' as begin select * from [DealStruc ...

  4. mybatis 按照条件查询

    mybatis 按照条件查询 @Autowired private StudentMapper studentMapper; @Override public Map getStudentList(i ...

  5. angular-代码段

    重复代码 <div ng-app="" ng-init="names=['Jani','Hege','Kai']"> <p>使用 ng- ...

  6. l洛谷 P2326 AKN’s PPAP

    P2326 AKN’s PPAP 题目描述 “I have a pen,I have an apple.Eh,Apple-Pen!. I have a pen,I have pineapple.En, ...

  7. UVA 436 - Arbitrage (II)(floyd)

    UVA 436 - Arbitrage (II) 题目链接 题意:给定一些国家货币的汇率.问是否能通过不断换货币使钱得到增长 思路:floyd,完事后推断一下有没有连到自己能大于1的情况 代码: #i ...

  8. JDBC连接mysql增删改查整体代码

    第一种比较low:用了statment,没有用preparedstatement.另外,插入时,不灵活,不能调用参数,但是如果直接给函数形参的话就会被SQL注入攻击,所以,最好在sql语句中使用?代表 ...

  9. C++_关于const 的全面总结

    C++中的constkeyword的使用方法很灵活.而使用const将大大改善程序的健壮性.本人依据各方面查到的资料进行总结例如以下,期望对朋友们有所帮助. Const 是C++中经常使用的类型修饰符 ...

  10. 从头认识Spring-3.4 简单的AOP日志实现-扩展添加检查订单功能,以便记录并检測输入的參数

    这一章节我们再上一个章节的基础上加上一个检查订单功能 1.domain 蛋糕类: package com.raylee.my_new_spring.my_new_spring.ch03.topic_1 ...