Land of Farms

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 539    Accepted Submission(s): 177

Problem Description
Farmer John and his brothers have found a new land. They are so excited and decide to build new farms on the land. The land is a rectangle and consists of N×M grids. A farm consists of one or more connected grids. Two grids are adjacent if they share a common border, i.e. their Manhattan distance is exactly 1. In a farm, two grids are considered connected if there exist a series of adjacent grids, which also belong to that farm, between them.

Farmer John wants to build as many farms as possible on the new land. It is required that any two farms should not be adjacent. Otherwise, sheep from different farms would fight on the border. This should be an easy task until several ancient farms are discovered.

Each of the ancient farms also consists of one or more connected grids. Due to the respect to the ancient farmers, Farmer John do not want to divide any ancient farm. If a grid from an ancient farm is selected in a new farm, other grids from the ancient farm should also be selected in the new farm. Note that the ancient farms may be adjacent, because ancient sheep do not fight each other.

The problem is a little complicated now. Can you help Farmer John to find a plan with the maximum number of farms?

 
Input
The first line of input contains a number T indicating the number of test cases (T≤200).

Each test case starts with a line containing two integers N and M, indicating the size of the land. Each of the following N lines contains M characters, describing the map of the land (1≤N,M≤10). A grid of an ancient farm is indicated by a single digit (0-9). Grids with the same digit belong to the same ancient farm. Other grids are denoted with a single character “.”. It is guaranteed that all test cases are valid.

 
Output
For each test case, output a single line consisting of “Case #X: Y”. X is the test case number starting from 1. Y is the maximum number of new farms.
 
Sample Input
3
3 4
..3.
023.
.211
2 3
...
...
4 4
1111
1..1
1991
1111
 
Sample Output
Case #1: 4
Case #2: 3
Case #3: 1
 
Source
 
Recommend
wange2014   |   We have carefully selected several similar problems for you:       
题意:  有一个农场大小为n*m  里面有一些古老的农田,你现在需要新建一些农田,要求新建的农田之间不能相连,古老的农田不可拆分,如果你选择了一块土地(原为古老的农田)建立新农田则需要把该块古老的农田全部包含。
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <iostream>
#include <cmath>
#include <map>
#include <bitset>
#include <stack>
#include <queue>
#include <vector>
#include <bitset>
#include <set>
#define MM(a,b) memset(a,b,sizeof(a));
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
#define CT continue
#define SC scanf char f[15][15];
int anc[16],flag[14],mp[12][12],cnta,ans,res;
int dx[]={0,0,1,-1},dy[]={1,-1,0,0},match[105],used[105];
vector<int> G[205];
int cas,r,l;
bitset<15> sta; void add_edge(int u,int v)
{
G[u].push_back(v);
G[v].push_back(u);
//if(sta==0) cout<<"u: "<<u<<" v:"<<v<<"\n";
} bool dfs(int u)
{
used[u]=1;
for(int i=0;i<G[u].size();i++){
int v=G[u][i],w=match[v];
if(w<0||(!used[w]&&dfs(w))){
match[u]=v;
match[v]=u;
return true;
}
}
return false;
} int bi_mactch()
{
int res=0;
MM(match,-1);
for(int i=1;i<=r;i++) for(int j=1;j<=l;j++){
int k=(i-1)*l+j;
if(match[k]<0){
MM(used,0);
if(dfs(k)) res++;
}
}
return res;
} int par[15]; int findr(int u)
{
if(par[u]!=u)
par[u]=findr(par[u]);
return par[u];
} void unite(int u,int v)
{
int ru=findr(u),rv=findr(v);
if(ru!=rv) par[ru]=rv;
} int num=0;
void sear(int i,int j)
{
if(f[i][j]>='0'&&f[i][j]<='9'){
int k=f[i][j]-'0';
if(!flag[k]) return;
mp[i][j]=-1;
for(int d=0;d<4;d++){
int tx=i+dx[d],ty=j+dy[d];
if(f[tx][ty]>='0'&&f[tx][ty]<='9'){
int k2=f[tx][ty]-'0';
if(flag[k2]) unite(k,k2);
}
else if(f[tx][ty]=='.') mp[tx][ty]=-1;
}
}
} void bgraph()
{
for(int i=1;i<=110;i++) G[i].clear();
for(int i=1;i<=r;i++)
for(int j=1;j<=l;j++)
if(f[i][j]=='.'&&!mp[i][j]){
num++;
int k=(i-1)*l+j;
//if(sta==0) cout<<"kk:"<<k<<"\n";
if(f[i-1][j]=='.'&&!mp[i-1][j]) add_edge(k,k-l);
if(f[i][j-1]=='.'&&!mp[i][j-1]) add_edge(k,k-1);
}
} void solve()
{
ans=0;
for(int k=0;k<=(1<<cnta)-1;k++){
res=0;MM(mp,0);MM(flag,0);
sta=k;
for(int i=0;i<cnta;i++) if(sta[i]) {
int w=anc[i+1];flag[w]=1;
par[w]=w;
}
for(int i=1;i<=r;i++) for(int j=1;j<=l;j++) sear(i,j);
for(int i=1;i<=cnta;i++)
if(flag[anc[i]]&&par[anc[i]]==anc[i]) res++;
num=0;bgraph();
ans=max(ans,res+num-bi_mactch());
}
} int main()
{
SC("%d",&cas);
int kk=0;
while(cas--){
SC("%d%d",&r,&l);
MM(flag,0);
cnta=0;
for(int i=1;i<=r;i++) {
SC("%s",f[i]+1);
for(int j=1;j<=l;j++)
if(f[i][j]!='.'){
int k=f[i][j]-'0';
if(!flag[k]){
flag[k]=1;
anc[++cnta]=k;
}
}
}
solve();
printf("Case #%d: %d\n",++kk,ans);
}
return 0;
}

  分析:

1.先2^10=10^3暴力枚举选择的古代的田,选择了后,在用并查集维护一下,能产生的牧田数。

2.删除选择的古代的田周围的普通田地,再用下网格的二分图,考虑不想邻的连接一条边,那么最后显然成成了,求这样一个最大团

3.二分图的最大团=补图的最大点独立集合=顶点数-最大匹配数

hdu 5556 Land of Farms 最大团+暴力的更多相关文章

  1. Land of Farms HDU - 5556 二分图匹配

    Farmer John and his brothers have found a new land. They are so excited and decide to build new farm ...

  2. 【HDOJ5556】Land of Farms(最大团)

    题意:给定n*m的网格图,上面只有字符'.' 和 数字0-9.其中数字表示这是该格是古老的土地,字符'.'表示该格只是普通的土地. 可以认为一块古老的农田由四联通的所有数字相同的格组成的块,一块普通的 ...

  3. hdu 4740 The Donkey of Gui Zhou(暴力搜索)

    题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=4740 [题意]: 森林里有一只驴和一只老虎,驴和老虎互相从来都没有见过,各自自己走过的地方不能走第二次 ...

  4. hdu 3183 A Magic Lamp rmq或者暴力

    A Magic Lamp Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Pro ...

  5. HDU 6395 Sequence 【矩阵快速幂 && 暴力】

    任意门:http://acm.hdu.edu.cn/showproblem.php?pid=6395 Sequence Time Limit: 4000/2000 MS (Java/Others)   ...

  6. 「国庆训练&知识学习」图的最大独立集与拓展(Land of Farms,HDU-5556)

    题意 一个\(N*M\)的矩阵,其中"."代表空地,"0-9"代表古代建筑,我们如果选择了一个编号的古代建筑想要建立,那么对应就要将全部该编号的建筑建立起来,如 ...

  7. HDU 4462:Scaring the Birds(暴力枚举+状态压缩)

    http://acm.hdu.edu.cn/showproblem.php?pid=4462 题意:有一个n*n的地图,有k个空地可以放稻草人,给出每个空地可以放的稻草人属性,属性中有个R代表这个位置 ...

  8. HDU 6697 Closest Pair of Segments (计算几何 暴力)

    2019 杭电多校 10 1007 题目链接:HDU 6697 比赛链接:2019 Multi-University Training Contest 10 Problem Description T ...

  9. HDU 3267 Graph Game(博弈论+图论+暴力)

    题面传送门 题意: 有一棵 \(n\) 个节点的图 \(G\),R 和 B 两个人轮流操作,R 先操作. 每次操作 R 可以染红任意一条未染色的边,B 可以染蓝任意一条未染色的边 R 的目标是染成一棵 ...

随机推荐

  1. Idea中maven的设置

    File->setting    输入MAVEN     看到右侧设置情况     Maven home directory 熟路本地moven 仓库目录:D:/springboot/apach ...

  2. 6.Linux查看哪个进程占用磁盘IO

    $ iotop -oP命令的含义:只显示有I/O行为的进程

  3. 【Trie】Phone List

    [题目链接]: https://loj.ac/problem/10049 [题意] 问是否存在一组公共前缀.如果存在输出“NO”,否则输出“YES” [题解] 首先建出Trie树来,然后开始记录所有的 ...

  4. MyBatis 源码篇-SQL 执行的流程

    本章通过一个简单的例子,来了解 MyBatis 执行一条 SQL 语句的大致过程是怎样的. 案例代码如下所示: public class MybatisTest { @Test public void ...

  5. SimpleDateFormat线程安全问题

    今天线上出现了问题,从第三方获取的日期为 2019-12-12 11:11:11,通过SimpleDateFormat转换格式后,竟然出现完全不正常的日期数据,经百度,得知SimpleDateForm ...

  6. 如何演讲-摘录自TED

    一.首先,只传递一个主要思想  想法是个很复杂的东西,你要对你的内容做减法,突出重点,只关注一个主要思想,也就是你最富有热情的观点,利用机会好好的阐述它.你要给出案例,分享案例,生动阐述所以,找到一个 ...

  7. CSP-S2019题解

    格雷码 €€£:我不抄自己辣!JOJO! 这题比那个SCOI的炒鸡格雷码好多了,甚至告诉你构造方法,所以... void wk(uLL kk) { int j=0; for(uLL i=n-1;~i; ...

  8. Python应用范围seo

    Python有许多OOP概念,包括类.对象.数据和方法.抽象.封装.继承和多态性等原则也可以使用Python实现和表示.python有几个高级函数,包括迭代器.生成器.列表分析器.lambda表达式和 ...

  9. SQL优化的总结和一些避免全盘扫描的注意事项

    1.应尽量避免在 where 子句中使用 != 或 <> 操作符,否则将引擎放弃使用索引而进行全表扫描. 2.应尽量避免在 where 子句中使用 or 来连接条件,如果一个字段有索引,一 ...

  10. Asp .Net Core 2.0 登录授权以及前后台多用户登录

    用户登录是一个非常常见的应用场景 .net core 2.0 的登录方式发生了点变化,应该是属于是良性的变化,变得更方便,更容易扩展. 配置 打开项目中的Startup.cs文件,找到Configur ...