POJ - 3020 Antenna Placement 二分图最大匹配
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 二分图最大匹配的更多相关文章
- [POJ] 3020 Antenna Placement(二分图最大匹配)
题目地址:http://poj.org/problem?id=3020 输入一个字符矩阵,'*'可行,'o'不可行.因为一个点可以和上下左右四个方向的一个可行点组成一个集合,所以对图进行黑白染色(每个 ...
- POJ 3020 Antenna Placement(二分图 匈牙利算法)
题目网址: http://poj.org/problem?id=3020 题意: 用椭圆形去覆盖给出所有环(即图上的小圆点),有两种类型的椭圆形,左右朝向和上下朝向的,一个椭圆形最多可以覆盖相邻的两 ...
- POJ 3020 Antenna Placement (二分图最小路径覆盖)
<题目链接> 题目大意:一个矩形中,有N个城市’*’,现在这n个城市都要覆盖无线,每放置一个基站,至多可以覆盖相邻的两个城市.问至少放置多少个基站才能使得所有的城市都覆盖无线? 解题分析: ...
- 二分图最大匹配(匈牙利算法) POJ 3020 Antenna Placement
题目传送门 /* 题意:*的点占据后能顺带占据四个方向的一个*,问最少要占据多少个 匈牙利算法:按坐标奇偶性把*分为两个集合,那么除了匹配的其中一方是顺带占据外,其他都要占据 */ #include ...
- poj 3020 Antenna Placement(最小路径覆盖 + 构图)
http://poj.org/problem?id=3020 Antenna Placement Time Limit: 1000MS Memory Limit: 65536K Total Sub ...
- POJ 3020 Antenna Placement 【最小边覆盖】
传送门:http://poj.org/problem?id=3020 Antenna Placement Time Limit: 1000MS Memory Limit: 65536K Total ...
- POJ 3020 Antenna Placement 最大匹配
Antenna Placement Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 6445 Accepted: 3182 ...
- POJ 3020 Antenna Placement【二分匹配——最小路径覆盖】
链接: http://poj.org/problem?id=3020 http://acm.hust.edu.cn/vjudge/contest/view.action?cid=22010#probl ...
- poj 3020 Antenna Placement (最小路径覆盖)
链接:poj 3020 题意:一个矩形中,有n个城市'*'.'o'表示空地,如今这n个城市都要覆盖无线,若放置一个基站, 那么它至多能够覆盖本身和相邻的一个城市,求至少放置多少个基站才干使得全部的城市 ...
随机推荐
- centos6.5 mysql 5.6修改root密码,以及创建用户并授权
mkdir -p mysql_home/{data,temp,undologs,logs} chown -R mysql:mysql /dbfiles/mysql_home mysql_install ...
- webrtc 学习资源1
1,http://www.webrtc.org/ webrtc官网,神马编译,神马下载,这里的解决方案才是最权威的. --------------------------------- 2,http ...
- MongoDB 项目集成 mongo-driver 3.4.2
第一次写技术!大白话讲讲.拿着用就可以了 本人是,NET的技术人员,会点JAVA所以很多不专业,见谅哈 刚刚开始使用mongo 整整搞了两天我才搞个半桶水,还是将就着用吧 随便把mongo在win的搭 ...
- Linux-正则表达式与三剑客
1 固化命令文件 登录时执行文件的顺序 /etc/profile /etc/profile.d ~/.bash_profile ~/.bashrc /etc/bashrc 非登录shell ~/.ba ...
- Rsyslog 日志相关内容
[root@server vusers_home]# rpm -ql rsyslog|more ###.so结尾为模块,模块有分im为输入模块,om 为输出模块/etc/logrotate ...
- SQL Server 2008将数据导出为脚本 [SQL Server]
之前我们要将一个表中的数据导出为脚本,那么只有在网上找一个导出数据的Script,然后运行就可以导出数据脚本了.现在在SQL Server 2008的Management Studio中增加了一个新特 ...
- Day03:集合、文件处理和函数基础
上节课复习: 1.总结 可变/不可变: 可变类型:list,dict 不可变类型:int,float,str,tuple ...
- web集群时代
随着业务的不断增加,我们的单台服务器承受不住需求,那么我们就需要对此进行伸缩,有两种维度,一种是纵向的也就是增大该台服务器的硬件,再者就是加新服务器与之前的机器组成集群对外提供服务,我们都知道前者是有 ...
- JQuery扩展插件Validate—5添加自定义验证方法
从前面的示例中不难看出validate中自带的验证方法足以满足一般的要求,对于特别的要求可以使用addMethod(name,method,message)添加自定义的验证规则,下面的示例中添加了一个 ...
- 调试 Hadoop 源代码
环境是 64bit Ubuntu 14.04 系统, jdk 1.7 以及 Eclipse Mars (4.5) 这里介绍两种调试 Hadoop 源代码的方法: 利用 Eclipse 远程调试工具和打 ...