ZOJ1654

来源:互联网 发布:php隐藏域名跳转代码 编辑:程序博客网 时间:2024/05/01 01:39

题意:给一个地图,分空地o 草地* 和墙壁#,可以在空地上放 向上下左右四个方向放激光【激光能穿过草无法穿墙】的机器人,问最多能放多少这样的机器人

题解:原理跟poj上那个 ”在一个点上放了以后该行该列都没发放“的原理是一样的

poj那道题是 每一行,每一列都算一块,然后X行和Y列的 交点【放置机器人的位置】就是 x-y 这条边

而这题有墙,所以 把每行和列都按照墙的分割,然后将 分块后的行列 连边【当他们的交点为空地时】

最后求一下最大匹配

#include<bits/stdc++.h>using namespace std;const int MAXN = 2505;#define _clr(x) memset(x, 0xff, sizeof(int) * MAXN)int mk[MAXN], match1[MAXN], match2[MAXN], mat[MAXN][MAXN], n, m;int path(int i){    for (int j = 0; j < m; j++)        if (mat[i][j] && !(mk[j]++) && (match2[j] < 0 || path(match2[j]))){          match1[i] = j;          match2[j] = i;          return 1;       }    return 0;}int hungary(){    int res(0);    _clr(match1);    _clr(match2);    for (int i = 0; i < n; i++)        if (match1[i] < 0){            memset(mk, 0, sizeof(mk));            res += path(i);        }    return res;}int nn,mm;char s[100][100];int xx[100][100],yy[100][100];void Gao(){    memset(mat,0,sizeof(mat));    memset(xx,0,sizeof(xx));    memset(yy,0,sizeof(yy));    cin>>nn>>mm;    for (int i=0;i<nn;i++)        scanf("%s",s[i]);    int numx=0,numy=0;    for (int i=0;i<nn;i++)    {        bool line=false;        for (int j=0;j<mm;j++)        {            if (s[i][j]!='#')            {                if (!line)                    numx++;                line=true;                xx[i][j]=numx;            }            if (s[i][j]=='#')                line=false;        }    }    for (int j=0;j<mm;j++)    {        bool line=false;        for (int i=0;i<nn;i++)        {            if (s[i][j]!='#')            {                if (!line)                    numy++;                line=true;                yy[i][j]=numy;            }            if (s[i][j]=='#')                line=false;        }    }    if (numx==0||numy==0)    {        cout<<0<<endl;        return;    }    for (int i=0;i<nn;i++)        for (int j=0;j<mm;j++)        {            if (s[i][j]=='o')            {                assert(xx[i][j]>=1);                assert(yy[i][j]>=1);                mat[xx[i][j]-1][yy[i][j]-1]=1;            }        }    assert(numx<=MAXN);    assert(numy<=MAXN);    n=numx;m=numy;    cout<<hungary()<<endl;}int main(){    int T,cas=1;    cin>>T;    while (T--)    {        printf("Case :%d\n",cas++);        Gao();    }        return 0;}

0 0