zoukankan      html  css  js  c++  java
  • HDU 1045

    二分图匹配

    题意:给你一个矩阵,X所在的地方是墙,往上面放碉堡,碉堡所在的行和列上的所有的点消灭掉。

    与最简单的二分图不同的是,有墙。

    做二分图的题,第一步要建图,在这里,二分图是一条边的两端分处于不同的点集、所以每找到一个点就把和他同一行、同一列的点都做同样的标记。遇到墙就停下

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    
    #define N 8
    int cnt_row, cnt_col;
    int row[N][N], col[N][N], r[N], c[N];
    char map[N][N];
    bool path[N][N], vis[N];
    
    int dfs(int rr)
    {
        for(int i=0;i<cnt_col;++i)
        {
            if(path[rr][i]&&vis[i]==false)
            {
                vis[i]=true;
                if(c[i]==-1||dfs(c[i]))
                {
                    c[i]=rr;
                    r[rr]=i;
                    return 1;
                }
            }
        }
        return 0;
    }
    int maxmatch()
    {
        int ans=0;
        memset(r,-1,sizeof(r));
        memset(c,-1,sizeof(c));
        for(int i=0;i<cnt_row;i++)
        {
            if(r[i]==-1)
            {
                memset(vis,false,sizeof(vis));
                ans+=dfs(i);
            }
        }
        return ans;
    }
    int main()
    {
        int n;
        while(~scanf("%d",&n)&&n)
        {
            for(int i = 0; i < n; ++i)
            {
                scanf("%s",map[i]);
            }
            memset(row,-1,sizeof(row));
            memset(col,-1,sizeof(col));
            cnt_row=cnt_col=0;
            for(int i=0;i<n;i++)
            {
                for(int j=0;j<n;j++)
                {
                    if(map[i][j]=='.'&&row[i][j]==-1)
                    {
                        for(int k=j;map[i][k]=='.'&&k<n;++k)
                        {
                            row[i][k]=cnt_row;
                        }
                        cnt_row++;
                    }
                    if(map[j][i]=='.'&&col[j][i]==-1)
                    {
                        for(int k=j;map[k][i]=='.'&&k<n;++k)
                        {
                            col[k][i]=cnt_col;
                        }
                        cnt_col++;
                    }
                }
            }
            memset(path,false,sizeof(path));
            for(int i=0;i<n;++i)
            {
                for(int j=0;j<n;++j)
                {
                    if(map[i][j]=='.')
                    {
                        path[row[i][j]][col[i][j]]=true;
                    }
                }
            }
            printf("%d
    ",maxmatch());
        }
        return 0;
    }
  • 相关阅读:
    第十二周工作总结
    第八周工作总结
    冲刺2
    冲刺1
    用户场景分析
    用户场景分析
    水王在哪
    课堂练习-4个数的和
    《大道至简》第一章读后感
    ELF Format 笔记(三)—— Section Types
  • 原文地址:https://www.cnblogs.com/qioalu/p/5445562.html
Copyright © 2011-2022 走看看