HDU1045 Fire Net 二分图匹配+思维

这道题乍一看就是DFS,但是写了半天发现写不出来QAQ…我好菜啊55555…

搜了题解发现有人用DFS,但是写的有点烦。。

据说正确的打开方式是二分图匹配,然而我怎么都想不到emmmmm…

附上大佬博客Orz:https://blog.csdn.net/rain722/article/details/72883242

                               https://blog.csdn.net/vsooda/article/details/7951096

就是把行、列进行缩点,然后匹配。。太强了Orz

附上AC代码:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;

const int MAXN=505;
int n1,n2,k;
int g[MAXN][MAXN];
int link[MAXN];
bool vis[MAXN];

bool dfs(int u)
{
    for(int v=0;v<n2;v++)
        if(g[u][v]&&!vis[v])
        {
            vis[v]=true;
            if(link[v]==-1||dfs(link[v]))
            {
                link[v]=u;
                return true;
            }
        }
    return false;
}
int main()
{
    int n;
    char s[6][6];
    int row[6][6],col[6][6];
    while(~scanf("%d",&n))
    {
        if(n==0)
            break;
        for(int i=0;i<n;i++)
            scanf("%s",s[i]);
        memset(row,-1,sizeof(row));
        memset(col,-1,sizeof(col));
        n1=0,n2=0;
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
            {
                if(s[i][j]=='.'&&row[i][j]==-1)
                {
                    int k=j;
                    while(s[i][k]=='.')//横向缩点
                        row[i][k]=n1,k++;//给相同的区域标记同一个数字
                    n1++;
                }
                if(s[i][j]=='.'&&col[i][j]==-1)
                {
                    int k=i;
                    while(s[k][j]=='.')//纵向缩点
                        col[k][j]=n2,k++;//给相同的区域标记同一个数字
                    n2++;
                }
            }
        memset(g,0,sizeof(g));
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
                if(s[i][j]=='.')
                    g[row[i][j]][col[i][j]]=1;
        int ans=0;
        memset(link,-1,sizeof(link));
        for(int u=0;u<n1;u++)
        {
            memset(vis,0,sizeof(vis));
            if(dfs(u))
                ans++;
        }
        printf("%d\n",ans);
    }
    return 0;
}

 

点赞