zoj_1002_最大匹配

 
//此题与zoj_1654差不多,但用最大匹配来做确实有点小试牛刀,可以用暴力
//直接从1654该过来的
#include<iostream>
#include<cstdio>
#include<memory.h>
#include<cstring>
using namespace std;
 
#define N 6
#define max 100
 
struct node    //相互链接的块
{
    int x_index,y_index;
}xy[N][N];
 
int n,m; //m行n列
int g[max][max];
char s[N][N];
int visit[max];
int pre[max];
int l,r,u,d;   //上下左右的标记
int p,q;    //二分图,一部分有p个点,另一部分有q个点
 
void solve()
{
    int i,j,k;
    p=q=-1;
    for(i=0;i<m;i++)
        for(j=0;j<n;j++)
            xy[i][j].x_index=xy[i][j].y_index=-1;
    for(i=0;i<m;i++)
    {
        for(j=0;j<n;j++)
            if(s[i][j]=='.')
            {
                if(xy[i][j].x_index==-1)
                {
                    p++;
                    k=j;
                    while(k>=0&&s[i][k]!='X')
                        k--;
                    l=++k;
                    k=j;
                    while(k<n&&s[i][k]!='X')
                        k++;
                    r=--k;
                    for(k=l;k<=r;k++)
                    {
                        xy[i][k].x_index=p;
                    }
                }
                if(xy[i][j].y_index==-1)
                {
                    q++;
                    k=i;
                    while(k>=0&&s[k][j]!='X')
                        k--;
                    u=++k;
                    k=i;
                    while(k<m&&s[k][j]!='X')
                            k++;
                    d=--k;
                    for(k=u;k<=d;k++)
                    {
                        xy[k][j].y_index=q;
                    }
                }
            }
    }
    memset(g,0,sizeof(g));
    for(i=0;i<m;i++)
    {
        for(j=0;j<n;j++)
            if(s[i][j]=='.')
            g[xy[i][j].x_index][xy[i][j].y_index]=1;
    }
}
 
bool dfs(int start)
{
    int i,temp;
    for(i=0;i<=q;i++)
        if(g[start][i]&&!visit[i])
        {
            visit[i]=1;
            temp=pre[i];
            pre[i]=start;
            if(temp==-1||dfs(temp))
                return true;
            pre[i]=temp;
        }
    return false;
}
 
int max_match()
{
    int i;
    memset(pre,int(-1),sizeof(pre));
    for(i=0;i<=p;i++)
    {
        memset(visit,0,sizeof(visit));
        dfs(i);
    }
    int ans=0;
    for(i=0;i<=q;i++)
        if(pre[i]!=-1)
            ans++;
    return ans;
}
 
int main()
{
    int t;
    int i,j;
    while(scanf("%d",&n)!=EOF&&n) //这里一定要注意判断n是否为0,之前没有判断错了n次,一直着都到buger,                 //测试数据又过了,真是背
    {
        m=n;
        for(i=0;i<m;i++)
        {
            getchar();
            scanf("%s",s[i]);
        }
        solve();
        printf("%d/n",max_match());
    }
    return 0;
}
 


你可能感兴趣的:(zoj_1002_最大匹配)