题意:给定一个图,L代表陆地,W代表水,C表示不确定,问你最多有多少岛。

析:首先给定的L周围必须是是W,只有这样才是最优的,因为如果是L,那么还得有另外的W来包围,不是最优的,那么剩下的就剩下C了,因为要是L多,那么肯定是一个岛屿只有一个L,这样是最优的,并且周围都是W,所以可以把C看成一个点,然后向周围上下左右连边,如果周围存在C,那么就连一条,最后求一个最大独立集就OK了,二分图的最大独立集等于二分图的顶点数 - 二分图的最大匹配。也就是求二分匹配。

代码如下:

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <cstring>
#include <set>
#include <queue>
#include <algorithm>
#include <vector>
#include <map>
#include <cctype>
#include <cmath>
#include <stack>
#include <sstream>
#include <list>
#include <assert.h>
#include <bitset>
#define debug() puts("++++");
#define gcd(a, b) __gcd(a, b)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define fi first
#define se second
#define pb push_back
#define sqr(x) ((x)*(x))
#define ms(a,b) memset(a, b, sizeof a)
#define sz size()
#define pu push_up
#define pd push_down
#define cl clear()
#define all 1,n,1
#define FOR(i,x,n) for(int i = (x); i < (n); ++i)
#define freopenr freopen("in.txt", "r", stdin)
#define freopenw freopen("out.txt", "w", stdout)
using namespace std; typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> P;
const int INF = 0x3f3f3f3f;
const double inf = 1e20;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int maxn = 50 + 50;
const LL mod = 1e9 + 7;
const int dr[] = {-1, 0, 1, 0};
const int dc[] = {0, 1, 0, -1};
const char *de[] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"};
int n, m;
const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
inline bool is_in(int r, int c) {
return r >= 0 && r < n && c >= 0 && c < m;
} struct Edge{
int to, next;
};
Edge edge[maxn*maxn];
int head[maxn*maxn], cnt;
int G[maxn][maxn];
char s[maxn][maxn]; void addEdge(int u, int v){
edge[cnt].to = v;
edge[cnt].next = head[u];
head[u] = cnt++;
}
bool vis[maxn][maxn];
bool used[maxn*maxn];
int match[maxn*maxn]; void dfs(int r, int c){
for(int i = 0; i < 4; ++i){
int x = r + dr[i];
int y = c + dc[i];
if(vis[x][y] || !is_in(x, y)) continue;
vis[x][y] = 1;
if(s[x][y] == 'L') dfs(x, y);
else s[x][y] = 'W';
}
} bool dfs(int u){
used[u] = true;
for(int i = head[u]; ~i; i = edge[i].next){
int v = edge[i].to, w = match[v];
if(w < 0 || !used[w] && dfs(w)){
match[u] = v;
match[v] = u;
return true;
}
}
return false;
} int main(){
scanf("%d %d", &n, &m);
for(int i = 0; i < n; ++i)
scanf("%s", s[i]);
int ans = 0;
FOR(i, 0, n) FOR(j, 0, m)
if(!vis[i][j] && s[i][j] == 'L'){
vis[i][j] = 1;
dfs(i, j); ++ans;
}
ms(G, -1); ms(head, -1); cnt = 0;
int idx = 0;
FOR(i, 0, n) FOR(j, 0, m)
if(s[i][j] == 'C') G[i][j] = idx++;
FOR(i, 0, n) FOR(j, 0, m)
if(i+j&1&&~G[i][j]){
for(int k = 0; k < 4; ++k){
int x = dr[k] + i;
int y = dc[k] + j;
if(is_in(x, y) && ~G[x][y]){
addEdge(G[i][j], G[x][y]);
addEdge(G[x][y], G[i][j]);
}
}
}
ms(match, -1);
int cnt = 0;
for(int i = 0; i < idx; ++i) if(match[i] < 0){
ms(used, 0); if(dfs(i)) ++cnt;
}
printf("%d\n", ans += idx - cnt);
return 0;
}

  

Gym 101201G Maximum Islands (最大独立集)的更多相关文章

  1. 【最小割】【Dinic】Gym - 101201G - Maximum Islands

    题意:方格内有些位置是水域,有些位置是陆地,有些位置是被云彩遮挡住了:让你自己规定被云彩遮挡住的地方是陆地还是水域,使得陆地个数最多.(均为四连通块) 显然与陆地邻接的云彩填成水比较优.其他云彩格子填 ...

  2. 2017萧山第5场(2016 Pacific Northwest - Division 1)

    B:Buggy Robot [题意] 一个n*m的地图(1≤n, m≤50),有一个入口和一个出口.给定一个命令序列(上,下,左,右),如果碰到障碍或者边际就忽略.问至少加入或删除多少个的命令,使得能 ...

  3. 2016-2017 ACM-ICPC Pacific Northwest Regional Contest (Div. 1) Solution

    A:Alphabet Solved. 签. #include<bits/stdc++.h> using namespace std; ]; ]; int main(){ scanf(); ...

  4. 要back的题目 先立一个flag

    要back的题目 目标是全绿!back一题删一题! acmm7 1003 1004 acmm8 1003 1004 sysu20181013 Stat Origin Title Solved A Gy ...

  5. Gym - 101670J Punching Power(CTU Open Contest 2017 最大独立集)

    题目: The park management finally decided to install some popular boxing machines at various strategic ...

  6. 2019牛客多校第五场 F maximum clique 1 状压dp+最大独立集

    maximum clique 1 题意 给出一个集合s,求每个子集的最大独立集的权值和(权值是独立集的点个数) 分析 n比较小,一股浓浓的暴力枚举每一个子集的感觉,但是暴力枚举模拟肯定会T,那么想一想 ...

  7. 最小顶点覆盖(Minimum Vertex Cover)与最大独立集(Maximum Independent Set)

    问题描述:就是在图中找最小的点集,使得覆盖所有边. 和独立集等价:独立集问题:在图中找最大的点集,使得点集内的所有点互不相连. 引理:顶点覆盖集和独立集互补. 上面这个引理使得这两个问题可以相互规约, ...

  8. 2019牛客多校第五场F maximum clique 1 最大独立集

    题意:给你n个数,现在让你选择一个数目最大的集合,使得集合中任意两个数的二进制表示至少有两位不同,问这个集合最大是多大?并且输出具体方案.保证n个数互不相同. 思路:容易发现,如果两个数不能同时在集合 ...

  9. 2019牛客暑期多校训练营(第五场)F maximum clique 1 二分图求最大独立集

    https://ac.nowcoder.com/acm/contest/885/F #include <bits/stdc++.h> //CLOCKS_PER_SEC #define se ...

随机推荐

  1. PostgreSQL性能极限

    目前已有很多PostgreSQL的系统在实际生产环境下管理着超过4TB的数据.一些PostgreSQL系统的极限值如下表所列: 极限值: 最大单个数据库大小 不限 最大数据单表大小 32 TB 单条记 ...

  2. java IDE 中安装 lombok plugin 插件,并使用 @Slf4j 注解打印日志初体验

    lombok 插件介绍: IntelliJ IDEA官方插件页面:https://plugins.jetbrains.com/plugin/6317-lombok-plugin 使用lombok之后, ...

  3. 完全卸载vs2013、vs2015的方法

    Visual Studio安装过程会安装好多组件,如果想要卸载的话会出现一些因难,在控制面板不容易卸载干净,在Linux下的命令都有--help参数来显示命令的用法,今天突发奇想,在控制台下输入vs2 ...

  4. bzoj2783 树

    第一行是两个整数N和S,其中N是树的节点数. 第二行是N个正整数,第i个整数表示节点i的正整数. 接下来的N-1行每行是2个整数x和y,表示y是x的儿子. 输出格式: 输出路径节点总和为S的路径数量. ...

  5. File根据inputstream复制文件到临时目录,使用完之后删除

    项目中有这个需求: 1)上传文件通过公司平台的校验,校验成功后,通过接口,返回文件流: 2)我们根据这个文件流进行操作.这里,先将文件流复制文件到项目临时目录WEB-INF/temp;文件使用完毕,删 ...

  6. Python链表与反链表

    # -*- coding:utf8 -*- #/usr/bin/env python class Node(object): def __init__(self, data, pnext = None ...

  7. 第十九课 golang中的下划线

    在 Golang 里, _ (下划线)是个特殊的标识符. 用在 import 在导包的时候,常见这个用法: 1 2 import _ "net/http/pprof" import ...

  8. NP、NPC、NP-hard问题的定义

    NP-hard问题    定义:NP-hard问题是这样的问题,只要其中某个问题可以在P时间内解决,那么所有的NP问题就都可以在P时间内解决了.NP-c问题就是NP-hard问题.但注意NP-hard ...

  9. 在Windows命令行窗口中输入并运行PHP代码片段(不需要php文件)的方法

    有时候只是简单的为了测试某个php函数的效果,以前总是需要建一个php文件,复制这个文件的路径,再通过web访问或者用php命令执行这个php文件. 一直想要怎么才能不用创建文件,才能直接执行PHP代 ...

  10. 单片机(TTL)与电脑RS232接口

    2010年11月28日 21:38 1.先介绍电脑上与单片机进行通讯的接口的名称 (1)一般是用电脑串口来进行通讯的,平常大家说的电脑的串口是指台式电脑主机后面的九针接口,如下图 ‍这个接口有个专业的 ...