zoj1654二分图

  题意:输入一个地图,*是草坪 # 是墙 o是空地。机器人只能放在空地上,且两个同行或者同列的机器人中间必须有墙,问最多可以放多少个机器人。

书上给出:......将行视为x    , 列视为 y. 求 x 与 y 这个2分图之间的最大匹配。

#include <cstdio>

#include <cstring>

#include <algorithm>

#include <climits>

#include <string>

#include <iostream>

#include <map>

#include <cstdlib>

#include <list>

#include <set>

#include <queue>

#include <stack>

#include<math.h>

using namespace std;

int numx;int numy;

const int maxn=51;

int link[maxn*maxn];

int xx[maxn*maxn],yy[maxn*maxn];

int x[maxn][maxn];

int y[maxn][maxn];

int used[maxn*maxn];

int g[maxn*maxn][maxn*maxn];

int dfs(int x)

{

    for(int i=1;i<=numy;i++){

        if(g[x][i]&&!used[i]){

            used[i]=1;

            if(link[i]==-1||dfs(link[i])){

                link[i]=x;

                return 1;

            }

        }

    }

    return 0;

}



void solve()

{

    int ans=0;

    for(int i=1;i<=numx;i++){

        memset(used,0,sizeof(used));

        if(dfs(i)) ans++;

    }

    cout<<ans<<endl;

}

int main()

{

    char str[maxn][maxn];

    int Icase;

    int n,m;

    scanf("%d",&Icase);

    int k=0;

    while(Icase--){

        memset(link,-1,sizeof(link));

        k++;

        memset(x,0,sizeof(x));

        memset(y,0,sizeof(y));

        memset(g,0,sizeof(g));

        scanf("%d%d",&m,&n);

        for(int i=0;i<m;i++)

            scanf("%s",str[i]);

        numx=0;numy=0;

        for(int i=0;i<m;i++){

            int flag=0;

            for(int j=0;j<n;j++){

                if(str[i][j]=='o'){

                    if(!flag) numx++;

                    x[i][j]=numx;flag=1;

                }

                else if(str[i][j]=='#') flag=0;

            }

        }

        for(int j=0;j<n;j++){

            int flag=0;

            for(int i=0;i<m;i++){

                if(str[i][j]=='o'){

                    if(!flag) numy++;

                    y[i][j]=numy;flag=1;

                }

                else if(str[i][j]=='#') flag=0;

            }

        }

        for(int i=0;i<m;i++)

            for(int j=0;j<n;j++)

            if(x[i][j]) g[x[i][j]][y[i][j]]=1;

        printf("Case :%d\n",k);

        solve();

    }

    return 0;

}

 

你可能感兴趣的:(二分图)