建模:

将所有的'*'作为X集合,边表示两个点相邻,如此建立的二部图,求出的最大匹配,需要进行处理:

我们发现对于已匹配点,都覆盖了两次,还要加上没有匹配到的点。

代码
//rank:47 132K 0MS 2010-06-06 15:55:48
//Type:二分匹配

#include
<stdio.h>
#include
<string.h>
#define HL 44
#define WL 11

int adj[HL*WL][5];
int mth[HL*WL];
bool used[HL*WL];
char ms[HL][WL];
int flg[HL][WL];
int dir[4][2] = {{0, -1}, {0, 1}, {1, 0}, {-1, 0}};
int n;

bool path(int u)
{
for (int v=1; v<=adj[u][0]; v++) {
int t = adj[u][v];
if (!used[t]) {
used[t]
= 1;
if (!mth[t] || path(mth[t])) {
mth[t]
= u;
return 1;
}
}
}
return 0;
}

int main()
{
int T, h, w;
int i, j, k;
int match;
scanf(
"%d", &T);
while (T--) {
scanf(
"%d%d", &h, &w);
for (i=0; i<h; i++) {
scanf(
"%s", ms[i]);
}
n
= 0;
for (i=0; i<h; i++) {
for (j=0; j<w; j++) {
if (ms[i][j] == '*') {
flg[i][j]
= ++n;
}
}
}
memset(adj,
0, sizeof(adj));
for (i=0; i<h; i++) {
for (j=0; j<w; j++) {
if (ms[i][j] == '*') {
for (k=0; k<4; k++) {
int x = i+dir[k][0];
int y = j+dir[k][1];
if (x>=0 && x<h
&& y>=0 && y<w
&& ms[x][y]=='*') {
int f1 = flg[i][j];
int f2 = flg[x][y];
adj[f1][
++adj[f1][0]] = f2;
}
}
}
}
}
match
= 0;
memset(mth,
0, sizeof(mth));
for (i=1; i<=n; i++) {
memset(used,
0, sizeof(used));
if (path(i)) {
match
++;
}
}
printf(
"%d\n", n-match/2);
}
return 0;
}

 

相关文章:

  • 2021-07-04
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-06-03
  • 2021-10-31
猜你喜欢
  • 2021-12-26
  • 2021-10-31
  • 2021-11-11
  • 2022-12-23
  • 2022-12-23
  • 2021-04-30
  • 2021-11-18
相关资源
相似解决方案