http://poj.org/problem?id=3020

首先注意到,答案的最大值是'*'的个数,也就是相当于我每用一次那个技能,我只套一个'*',是等价的。

所以,每结合一对**,则可以减少一次使用,所以就是找**的最大匹配数目。

对于每一个*,和它的上下左右连接一条边(如果是*才连)

那么,这个图是一个二分图,怎么找到左边集合S,右边集合T呢?

我的做法是染色一次,就可以。

这题应该不能贪心吧。

3 5

*****

o***o

o*o*o

其实也可以不分开S、T

跑一发最大匹配,然后匹配数 / 2即可。意思就是match[1] = 2,也可以match[2] = 1,但是两者是只算一个匹配。

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <assert.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL; #include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <bitset>
const int maxn = + ;
char str[maxn][maxn];
int a[maxn][maxn];
struct Node {
int u, v, tonext;
}e[maxn * maxn * ];
int first[maxn * maxn * ], num;
void addEdge(int u, int v) {
++num;
e[num].u = u, e[num].v = v;
e[num].tonext = first[u];
first[u] = num;
}
int match[maxn * maxn * ], book[maxn * maxn * ], DFN;
bool dfs(int u) {
for (int i = first[u]; i; i = e[i].tonext) {
int v = e[i].v;
if (book[v] == DFN) continue;
book[v] = DFN;
if (match[v] == || dfs(match[v])) {
match[v] = u;
return true;
}
}
return false;
}
vector<int>vc;
int hungary() {
memset(match, , sizeof match);
int ans = ;
for (int i = ; i < vc.size(); ++i) {
++DFN;
if (dfs(vc[i])) ans++;
}
return ans;
}
int col[maxn * maxn * ];
void ran(int cur, int which) {
col[cur] = which;
book[cur] = DFN;
for (int i = first[cur]; i; i = e[i].tonext) {
int v = e[i].v;
if (book[v] == DFN) continue;
ran(v, !which);
}
}
void work() {
memset(first, , sizeof first);
num = ;
int to = ;
int n, m;
cin >> n >> m;
for (int i = ; i <= n; ++i) {
scanf("%s", str[i] + );
}
memset(a, , sizeof a);
for (int i = ; i <= n; ++i) {
for (int j = ; j <= m; ++j) {
if (str[i][j] == '*') {
a[i][j] = ++to;
}
}
}
for (int i = ; i <= n; ++i) {
for (int j = ; j <= m; ++j) {
if (a[i][j + ]) addEdge(a[i][j], a[i][j + ]);
if (a[i + ][j]) addEdge(a[i][j], a[i + ][j]);
if (a[i][j - ]) addEdge(a[i][j], a[i][j - ]);
if (a[i - ][j]) addEdge(a[i][j], a[i - ][j]);
}
}
memset(col, -, sizeof col);
++DFN;
for (int i = ; i <= to; ++i) {
if (book[i] != DFN) ran(i, );
}
vc.clear();
for (int i = ; i <= to; ++i) {
if (col[i] == ) vc.push_back(i);
}
cout << to - hungary() << endl;
} int main() {
#ifdef local
freopen("data.txt", "r", stdin);
// freopen("data.txt", "w", stdout);
#endif
int t;
cin >> t;
while (t--) work();
return ;
}

POJ - 3020  Antenna Placement 二分图最大匹配的更多相关文章

  1. [POJ] 3020 Antenna Placement(二分图最大匹配)

    题目地址:http://poj.org/problem?id=3020 输入一个字符矩阵,'*'可行,'o'不可行.因为一个点可以和上下左右四个方向的一个可行点组成一个集合,所以对图进行黑白染色(每个 ...

  2. POJ 3020 Antenna Placement(二分图 匈牙利算法)

    题目网址:  http://poj.org/problem?id=3020 题意: 用椭圆形去覆盖给出所有环(即图上的小圆点),有两种类型的椭圆形,左右朝向和上下朝向的,一个椭圆形最多可以覆盖相邻的两 ...

  3. POJ 3020 Antenna Placement (二分图最小路径覆盖)

    <题目链接> 题目大意:一个矩形中,有N个城市’*’,现在这n个城市都要覆盖无线,每放置一个基站,至多可以覆盖相邻的两个城市.问至少放置多少个基站才能使得所有的城市都覆盖无线? 解题分析: ...

  4. 二分图最大匹配(匈牙利算法) POJ 3020 Antenna Placement

    题目传送门 /* 题意:*的点占据后能顺带占据四个方向的一个*,问最少要占据多少个 匈牙利算法:按坐标奇偶性把*分为两个集合,那么除了匹配的其中一方是顺带占据外,其他都要占据 */ #include ...

  5. poj 3020 Antenna Placement(最小路径覆盖 + 构图)

    http://poj.org/problem?id=3020 Antenna Placement Time Limit: 1000MS   Memory Limit: 65536K Total Sub ...

  6. POJ 3020 Antenna Placement 【最小边覆盖】

    传送门:http://poj.org/problem?id=3020 Antenna Placement Time Limit: 1000MS   Memory Limit: 65536K Total ...

  7. POJ 3020 Antenna Placement 最大匹配

    Antenna Placement Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6445   Accepted: 3182 ...

  8. POJ 3020 Antenna Placement【二分匹配——最小路径覆盖】

    链接: http://poj.org/problem?id=3020 http://acm.hust.edu.cn/vjudge/contest/view.action?cid=22010#probl ...

  9. poj 3020 Antenna Placement (最小路径覆盖)

    链接:poj 3020 题意:一个矩形中,有n个城市'*'.'o'表示空地,如今这n个城市都要覆盖无线,若放置一个基站, 那么它至多能够覆盖本身和相邻的一个城市,求至少放置多少个基站才干使得全部的城市 ...

随机推荐

  1. [转]FPGA实践——基于ROM访问的直接波形合成

    本文原创,转载请注明出处:http://www.cnblogs.com/risten/p/4166169.html 1.系统原理 通过频率控制字选择相位步进,产生访问ROM的地址,进而控制DAC的输出 ...

  2. 编辑xml文件时不能自动提示问题的解决

    在编辑xml文件时,eclipse总是不能自动提示,在网上找了一些资料,大部分都是说关于xml editor配置的,下面也把这个方法罗列在下面,以供参考: 解决办法:在eclipse的菜单里,找到wi ...

  3. tomcat 启动增加参数

    linux: JAVA_OPTS="$JAVA_OPTS  -Dconfig.type=inte2 -Xms2048m -Xmx2048m -XX:PermSize=128m -XX:Max ...

  4. Hibernate 模糊查询 ' %?% ' SQL执行异常

    今天我在使用Hibernate 的SQL预编译之后注入参数的形式写了一条模糊查询语句.刚开始我是这么写的

  5. CodeForces - 840D:(主席树求出现区间出现次数大于某值的最小数)

    Once, Leha found in the left pocket an array consisting of n integers, and in the right pocket q que ...

  6. oracle 左右链接

    数据表的连接有: 1.内连接(自然连接): inner只有两个表相匹配的行才能在结果集中出现 2.外连接: 包括 (1)左外连接(左边的表不加限制) (2)右外连接(右边的表不加限制) (3)全外连接 ...

  7. JUC类图

    JUC的类图总览.

  8. js 拦截 窗体关闭事件

    <script type="text/javascript">   <!--         window.onbeforeunload = onbeforeun ...

  9. NodeJS REST API with MySQL and Express

    http://www.nodewiz.biz/nodejs-rest-api-with-mysql-and-express/ NPM Modules Express felixge/node-mysq ...

  10. CF-798A

    A. Mike and palindrome time limit per test 2 seconds memory limit per test 256 megabytes input stand ...