hdu5093Battle ships(二分图)

来源:互联网 发布:淘宝有好看的衣服牌子 编辑:程序博客网 时间:2024/05/17 16:54

这个题目刚开始看根本开不出来是二分图,后来问了别人看了题解才搞懂,这个题是按照行和列再加上冰山然后分区域,然后因为行列不能挨着,所以把他们分成两个集合,然后一匹配就出来了

#include <iostream>#include <string.h>#include <stdio.h>using namespace std;const int MAXN =60;const int MAXM =3600;int linker[MAXM];bool used[MAXM];char s[MAXN][MAXN];int h[MAXN][MAXN];int l[MAXN][MAXN];bool g[MAXM][MAXM];int un,vn;bool dfs(int u){    for(int v=0; v<vn; v++)        if(g[u][v]&&!used[v])        {            used[v]=true;            if(linker[v]==-1||dfs(linker[v]))            {                linker[v]=u;                return true;            }        }    return false;}int hungary(){    int res=0;    memset(linker,-1,sizeof(linker));    for(int u=0; u<un; u++)    {        memset(used,false,sizeof(used));        if(dfs(u))            res++;    }    return res;}void init(){    un=0;    vn=0;    memset(s,0,sizeof(s));    memset(h,0,sizeof(h));    memset(l,0,sizeof(l));    memset(g,0,sizeof(g));}int main(){    int T,n,m;    cin>>T;    while(T--)    {        init();        cin>>n>>m;        for(int i=0; i<n; i++)            scanf("%s",s[i]);        for(int i=0; i<n; i++)        {            for(int j=0; j<m; j++)            {                if(s[i][j]=='*')                {                    h[i][j]=un;                }                if(s[i][j]=='#')//遇到冰山就++,意思是跟之前的区域区分开来                    un++;            }            un++;        }        for(int i=0; i<m; i++)        {            for(int j=0; j<n; j++)            {                if(s[j][i]=='*')                    l[j][i]=vn;                if(s[j][i]=='#')                    vn++;            }            vn++;        }        for(int i=0;i<n;i++)            for(int j=0;j<m;j++)        {            if(s[i][j]=='*')            {                g[h[i][j]][l[i][j]]=1;//这块是加边的地方            }        }        int ans=hungary();        cout<<ans<<endl;    }    return 0;}
0 0
原创粉丝点击