您的位置:首页 > 其它

bzoj2150

2016-03-30 08:03 316 查看
水水水。。

裸最小路径覆盖。。

我为何这么水。

#include <cstdio>
#include <cstring>
using namespace std;

int dx[5],dy[5];

int n,m,r,c,sz;
bool a[55][55];

struct edge {
int v,next;
}e[10010];
int cnt,head[5010];

int Linkx[5010],Linky[5010];
bool vis[5010];

int read_int () {
char c = getchar();
int re = 0;
for(;c > '9' || c < '0';c = getchar());
for(;c >= '0' && c <= '9';c = getchar())
re = re * 10 + c - '0';
return re;
}

void adde (int u,int v) {
e[cnt].v = v;
e[cnt].next = head[u];
head[u] = cnt++;
}

int cal (int x,int y) {
return (x - 1) * m + y;
}

int dfs (int u) {
for(int i = head[u];i != -1;i = e[i].next) {
int v = e[i].v;
if(vis[v])
continue;
vis[v] = 1;

if(!Linky[v] || dfs(Linky[v])) {
Linkx[u] = v;
Linky[v] = u;
return 1;
}
}
return 0;
}

int main () {
memset(head,-1,sizeof head);
n = read_int();
m = read_int();
r = read_int();
c = read_int();
sz = n * m;
dx[1] = -r;
dy[1] = -c;
dx[2] = -c;
dy[2] = -r;
dx[3] = -r;
dy[3] = c;
dx[4] = -c;
dy[4] = r;
for(int i = 1;i <= n;++i) {
for(int j = 1;j <= m;++j) {
if(getchar() == '.') {
a[i][j] = 1;
for(int k = 1;k <= 4;++k) {
int x = i + dx[k];
int y = j + dy[k];
if(x >= 1 && x <= n && y >= 1 && y <= m && a[x][y])
adde(cal(x,y),cal(i,j) + n * m);
}
}
else sz--;
}
getchar();
}

int ans = 0;
for(int i = 1;i <= n * m;++i) {
if(!Linkx[i]) {
memset(vis,0,sizeof vis);
ans += dfs(i);
}
}
printf("%d\n",sz - ans);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: