UVA Live 7958 (Codeforces Gym 101201G) Maximum Islands 二分图染色+匹配
2017-08-24 01:10
921 查看
https://icpcarchive.ecs.baylor.edu/external/79/7958.pdf
7958 Maximum Islands
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.
Input
The input fle contains several test cases, each of them as described below.
The frst line 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
For each test case, print, on a single line, a single integer indicating the maximum number of islands
that is consistent with the given grid.
Sample Input
5 4
LLWL
CCCC
CCCC
CCCC
LWLL
Sample Output
8
给你一个地图,L表示陆地,W表示水,C表示你可以任意安排,问最多有多少个陆地联通块。
先把所有已知陆地联通块dfs。接着,把不和陆地相邻的所有C区域安排为陆地,最优情况肯定是一个格子为一片陆地。
要构造二分图,就要黑白染色。染色之后,把相邻的C互相连边,对所有C组成的图求最大独立集。
当然,不黑白染色也可以,只是这时会有重边,数组要开够。
说道这里我就要吐槽了!这题亲测,数据范围应该是N<=60,然而题目里却是40,好坑啊!
导致我调到现在,WA了二十几次。
#include <cstdio>
#include <iostream>
#include <string.h>
#include <string>
#include <map>
#include <queue>
#include <vector>
#include <set>
#include <algorithm>
#include <math.h>
#include <cmath>
#include <stack>
#define mem0(a) memset(a,0,sizeof(a))
#define meminf(a) memset(a,0x3f,sizeof(a))
using namespace std;
typedef long long ll;
typedef long double ld;
const int maxn=65,inf=0x3f3f3f3f;
const ll llinf=0x3f3f3f3f3f3f3f3f;
const ld pi=acos(-1.0L);
int match[maxn*maxn];
int p[maxn][maxn],head[maxn*maxn];
bool visit[maxn][maxn],v[maxn*maxn];
char s[maxn][maxn];
int dir[4][2];
int n,m,num;
struct Edge {
int from,to,pre;
};
Edge edge[maxn*maxn*2];
void addedge(int from,int to) {
edge[num]=(Edge){from,to,head[from]};
head[from]=num++;
edge[num]=(Edge){to,from,head[to]};
head[to]=num++;
}
void dfs(int i,int j) {
visit[i][j]=1;
for (int k=0;k<4;k++) {
int x=i+dir[k][0],y=j+dir[k][1];
if (x>0&&y>0&&x<=n&&y<=m)
if (!visit[x][y]&&s[x][y]=='L') dfs(x,y);
if (s[x][y]=='C') s[x][y]='W';
}
}
bool hungary(int now) {
for (int i=head[now];i!=-1;i=edge[i].pre) {
int to=edge[i].to;
if (!v[to]) {
v[to]=1;
if (!match[to]||hungary(match[to])) {
match[to]=now;match[now]=to;
return true;
}
}
}
return false;
}
int main() {
dir[0][0]=dir[1][0]=dir[2][1]=dir[3][1]=0;
dir[0][1]=dir[2][0]=1;dir[1][1]=dir[3][0]=-1;
int i,j,k,ans=0;
scanf("%d%d",&n,&m);
for (i=1;i<=n;i++) {
scanf("%s",s[i]+1);
}
mem0(visit);
for (i=1;i<=n;i++)
for (j=1;j<=m;j++)
if (!visit[i][j]&&s[i][j]=='L') dfs(i,j),ans++;
int cnt=0;
memset(head,-1,sizeof(head));
num=0;
for (i=1;i<=n;i++)
for (j=1;j<=m;j++)
if (s[i][j]=='C')
p[i][j]=++cnt;
for (i=1;i<=n;i++)
for (j=1;j<=m;j++)
if (s[i][j]=='C'&&(i+j)%2==0)
for (k=0;k<4;k++) {
int x=i+dir[k][0],y=j+dir[k][1];
if (x>0&&y>0&&x<=n&&y<=m)
if (s[x][y]=='C') addedge(p[i][j],p[x][y]);
}
int sum=0;
mem0(match);
for (i=1;i<=cnt;i++)
if (!match[i]) {
mem0(v);v[i]=1;
if (hungary(i)) sum++;
}
ans+=cnt-sum;
printf("%d\n",ans);
return 0;
}
7958 Maximum Islands
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.
Input
The input fle contains several test cases, each of them as described below.
The frst line 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
For each test case, print, on a single line, a single integer indicating the maximum number of islands
that is consistent with the given grid.
Sample Input
5 4
LLWL
CCCC
CCCC
CCCC
LWLL
Sample Output
8
给你一个地图,L表示陆地,W表示水,C表示你可以任意安排,问最多有多少个陆地联通块。
先把所有已知陆地联通块dfs。接着,把不和陆地相邻的所有C区域安排为陆地,最优情况肯定是一个格子为一片陆地。
要构造二分图,就要黑白染色。染色之后,把相邻的C互相连边,对所有C组成的图求最大独立集。
当然,不黑白染色也可以,只是这时会有重边,数组要开够。
说道这里我就要吐槽了!这题亲测,数据范围应该是N<=60,然而题目里却是40,好坑啊!
导致我调到现在,WA了二十几次。
#include <cstdio>
#include <iostream>
#include <string.h>
#include <string>
#include <map>
#include <queue>
#include <vector>
#include <set>
#include <algorithm>
#include <math.h>
#include <cmath>
#include <stack>
#define mem0(a) memset(a,0,sizeof(a))
#define meminf(a) memset(a,0x3f,sizeof(a))
using namespace std;
typedef long long ll;
typedef long double ld;
const int maxn=65,inf=0x3f3f3f3f;
const ll llinf=0x3f3f3f3f3f3f3f3f;
const ld pi=acos(-1.0L);
int match[maxn*maxn];
int p[maxn][maxn],head[maxn*maxn];
bool visit[maxn][maxn],v[maxn*maxn];
char s[maxn][maxn];
int dir[4][2];
int n,m,num;
struct Edge {
int from,to,pre;
};
Edge edge[maxn*maxn*2];
void addedge(int from,int to) {
edge[num]=(Edge){from,to,head[from]};
head[from]=num++;
edge[num]=(Edge){to,from,head[to]};
head[to]=num++;
}
void dfs(int i,int j) {
visit[i][j]=1;
for (int k=0;k<4;k++) {
int x=i+dir[k][0],y=j+dir[k][1];
if (x>0&&y>0&&x<=n&&y<=m)
if (!visit[x][y]&&s[x][y]=='L') dfs(x,y);
if (s[x][y]=='C') s[x][y]='W';
}
}
bool hungary(int now) {
for (int i=head[now];i!=-1;i=edge[i].pre) {
int to=edge[i].to;
if (!v[to]) {
v[to]=1;
if (!match[to]||hungary(match[to])) {
match[to]=now;match[now]=to;
return true;
}
}
}
return false;
}
int main() {
dir[0][0]=dir[1][0]=dir[2][1]=dir[3][1]=0;
dir[0][1]=dir[2][0]=1;dir[1][1]=dir[3][0]=-1;
int i,j,k,ans=0;
scanf("%d%d",&n,&m);
for (i=1;i<=n;i++) {
scanf("%s",s[i]+1);
}
mem0(visit);
for (i=1;i<=n;i++)
for (j=1;j<=m;j++)
if (!visit[i][j]&&s[i][j]=='L') dfs(i,j),ans++;
int cnt=0;
memset(head,-1,sizeof(head));
num=0;
for (i=1;i<=n;i++)
for (j=1;j<=m;j++)
if (s[i][j]=='C')
p[i][j]=++cnt;
for (i=1;i<=n;i++)
for (j=1;j<=m;j++)
if (s[i][j]=='C'&&(i+j)%2==0)
for (k=0;k<4;k++) {
int x=i+dir[k][0],y=j+dir[k][1];
if (x>0&&y>0&&x<=n&&y<=m)
if (s[x][y]=='C') addedge(p[i][j],p[x][y]);
}
int sum=0;
mem0(match);
for (i=1;i<=cnt;i++)
if (!match[i]) {
mem0(v);v[i]=1;
if (hungary(i)) sum++;
}
ans+=cnt-sum;
printf("%d\n",ans);
return 0;
}
相关文章推荐
- Gym 101201F Illumination 2-sat+ G - Maximum Islands Gym - 101201G二分图染色+匹配
- UVALive 7958|Gym 101201G|Maximum Islands|二分图|最大独立点集
- UVA Live 7693 (Codeforces Gym 101201B) Buggy Robot DP+bfs
- UVA Live 6129 (Codeforces Gym 100642H) Sofa, So Good 最小费用流
- Codeforces Gym 101128F (UVA Live 7277) Landscaping 最小割
- UVALive 6851 The Programmers(二分图多重匹配)
- codeforces Gym 100286J Javanese Cryptoanalysis (二染色)
- UVALive - 7008 Tactical Multiple Defense System——二分图最大匹配
- UVALive 4043 Ants(二分图最佳完美匹配、KM)
- Codeforces Round #360 (Div. 2)——C. NP-Hard Problem(BFS染色判二分图)
- UVALive-5013 Similarity(二分图最大权匹配)
- UVALive - 6887 Book Club (二分图求最大匹配||网络流求最大匹配)
- UVALive 4043 Ants(二分图最佳完美匹配、KM)
- Codeforces Gym 101173B / BZOJ 4788 Bipartite Blanket 二分图Hall定理+状态压缩DP
- [codevs1022]覆盖(染色+二分图最大匹配)
- uvalive 2966 求一个二分图 所有的完美匹配
- UVALive - 4043 Ants (二分图最大权匹配)
- CSU 1623 Inspectors(二分图最大权匹配 KM算法)(UVAlive 6879)
- UVALIVE 3523 双连通分量+二分图染色
- Codeforces Round #360 (Div. 2) 前三题题解【简单模拟+思维+二分图判定二分染色】