UVALive 7958|Gym 101201G|Maximum Islands|二分图|最大独立点集
来源:互联网 发布:淘宝店刚开始卖什么好 编辑:程序博客网 时间:2024/06/05 04:14
Description
You are mapping a faraway planet using a satellite.
Your satellite has captured an image of the planet’s surface. The photographed section can be modeled as a grid. Each grid cell is either land, water, or covered by clouds. Clouds mean that the surface could either be land or water, but we can’t tell.
An island is a set of connected land cells. Two cells are considered connected if they share an edge.
Given the image, determine the maximum number of islands that is consistent with the given information.
Translation
你通过卫星获得了遥远星球的照片。照片通过
一个岛屿由一片连通的陆地格子表示。两个格子连通即两个格子相邻。
请你计算地图里最多能有多少个岛屿。
Input
The first line of input contains two space-separated integers n and m (1 ≤ n, m ≤ 40).
Each of the next n lines contains m characters, describing the satellite image. Land cells are
denoted by ‘L’, water cells are denoted by ‘W’, and cells covered by clouds are denoted by ‘C’.
Output
Print, on a single line, a single integer indicating the maximum number of islands that is consistent
样例输入
5 4LLWLCCCCCCCCCCCCLWLL
样例输出
8
题解
一个很显然的结论:扩展已有的L是不好的(没有意义,将这些扩展的L改为W不影响答案)。所以我们可以将已有的L的四周的C直接设为W。然后剩下的C,显然一个岛一个格子的陆地就足够了(因为扩展没有意义)。
也就是说,问题已经变成对于已有的一些点,挑出最多的点使得这些点互不相邻(有边连接)。这个是最大独立点集,是NP问题,但是如果是二分图就好做了。我们可以想到,因为这个图比较规整,是格子图,因此我们黑白染色后就是二分图了(人话就是(x+y)%2的值相同的点间颜色一样,不可能相连).
也就是说,我们可以将所有的点划分为两个集合,这两组点间有边。联系到二分图的最大独立点集,即为顶点数减去最大匹配的解,因此采用匈牙利算法解决。
#include <cstdio>#include <cstring>#define FOR(i,j,k) for(i=j;i<=k;++i)const int dx[] = {1, -1, 0, 0};const int dy[] = {0, 0, 1, -1};const int N = 2048, M = N * 8;char mp[64][64];bool vi[64][64];int h[N], p[M], v[M], edge = 0;int vis[N], match[N];int n, m;int id(int x, int y) { return (x - 1) * m + y;}int add(int a, int b) { p[++edge] = h[a]; v[edge] = b; h[a] = edge; p[++edge] = h[b]; v[edge] = a; h[b] = edge;}// 寻找已有的连成一片的陆地(岛屿),四周设为Wvoid dfsLands(int x, int y) { int i, nx, ny; if (vi[x][y]) return; vi[x][y] = 1; for (i = 0; i < 4; ++ i) { nx = x + dx[i]; ny = y + dy[i]; if (nx < 1 || nx > n || ny < 1 || ny > m || vi[nx][ny]) continue; if (mp[nx][ny] == 'C') mp[nx][ny] = 'W'; if (mp[nx][ny] == 'L') dfsLands(nx, ny); }}// 构图void dfsClouds(int x, int y) { int i, nx, ny; if (vi[x][y]) return; vi[x][y] = 1; for (i = 0; i < 4; ++ i) { nx = x + dx[i]; ny = y + dy[i]; if (nx < 1 || nx > n || ny < 1 || ny > m || mp[nx][ny] != 'C') continue; add(id(x, y), id(nx, ny)); dfsClouds(nx, ny); }}int hungary(int x) { if (vis[x]) return 0; vis[x] = 1; for (int i = h[x]; i; i = p[i]) if (!match[v[i]] || hungary(match[v[i]])) { match[v[i]] = x; return 1; } return 0;}int main() { int i, j, ans = 0; scanf("%d%d", &n, &m); FOR(i,1,n) scanf("%s", mp[i] + 1); FOR(i,1,n) FOR(j,1,m) if (mp[i][j] == 'L' && !vi[i][j]) dfsLands(i, j), ++ans; FOR(i,1,n) FOR(j,1,m) if (mp[i][j] == 'C') dfsClouds(i, j), ++ans; memset(match, 0, sizeof match); FOR(i,1,n) FOR(j,1,m) if ((i + j) % 2 == 0) { memset(vis, 0, sizeof vis); ans -= hungary(id(i, j)); } printf("%d\n", ans); return 0;}
- UVALive 7958|Gym 101201G|Maximum Islands|二分图|最大独立点集
- Codeforces Gym 101201G Maximum Islands (dfs求联通块+最大独立集)
- UVA Live 7958 (Codeforces Gym 101201G) Maximum Islands 二分图染色+匹配
- GYM 100523 I【二分图的最大点权独立集】
- UVALive 3415 浅谈二分图最大点独立集架构建模
- ZOJ1137 二分图的最大独立点集 匈牙利算法
- POJ 3692 - Kindergarten 二分图的最大独立点集
- Poj 3692 Kindergarten 二分图最大独立点集
- bzoj3175 [ TJOI2013 ] -- 二分图最大点独立集
- BZOJ 4808 二分图最大点独立集
- POJ 3692 二分图最大点独立集 解题报告
- UVALive 3415 Guardian of Decency(二分图最大独立集)
- UVaLive 3415 保守的老师(二分图最大独立集)
- uvalive 4288 Cat vs. Dog 求二分图的最大独立集
- 二分图最大匹配,最小点覆盖,最小路径覆盖,二分图最大独立集
- 二分图最大独立集
- 二分图最大独立集
- 二分图最大独立集
- Mac OSX 正确地同时安装Python 2.7 和Python3
- 【Keras】MLP多层感知机
- 静态顺序表用C实现的各种操作
- Exact Change
- B. XK Segments(暴力)
- UVALive 7958|Gym 101201G|Maximum Islands|二分图|最大独立点集
- xXx方块 测试版
- HDU 1231 题解
- 解决Cannot change version of project facet Dynamic web module to 2.5
- 上机练习题——接口(课堂练习2)
- C# ref,值传递转换为引用传递
- Java 多线程学习笔记3
- J
- cadence vmanager(十) vplan与vmanager结合使用的例子