• HDU 1045 Fire Net(图匹配)


    题目大意:
    这个是以前做过的一道DFS题目,当时是完全暴力写的。
    给你一个N代表是N*N的矩阵,矩阵内 ‘X’代表墙, ‘.’代表通道。
    问这个矩阵内最多可以放几个碉堡, 碉堡不能在同一行或者同一列,除非他们中间有墙。
     
    二分图做法思想:我们用行去匹配列,判断最大匹配数。
    我们需要重新构图, 假如一行中 (  ..X..X.. ) 那么在这一行中我们其实是可以分割到三个不同的行(因为中间隔有X)。然后对这个三个行进行编号。同理列也是一样的。当我们完全构好图后就可以做完全匹配了,其他的跟HDU 1083 Courses(最大匹配模版题) 差不多。
    吐槽一下杭电,代码写好了提交用C++WA  G++过 妈蛋
     
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #include<iostream>
    using namespace std;
    #define maxn 50
    bool G[maxn][maxn];///重新构图存储
    bool vis[maxn];///标记点是否被遍历过
    char maps[maxn][maxn];///地图存储
    int P[maxn];///第 i  行匹配的第 P[i]列
    int n, m, N;///重构图后是m行 n列
    struct Node
    {
        int x, y;
    }NodeInfo[maxn][maxn];///保存每个点重构图后所在的行和列
    
    bool Find(int u)
    {
        for(int i=0; i<n; i++)
        {
           if(G[u][i] && !vis[i])
           {
               vis[i] = true;
               if( P[i] == -1 || Find(P[i]))
               {
                   P[i] = u;
                   return true;
               }
           }
        }
        return false;
    }
    void MakeMaps()
    {
        m = 0, n = 0;///行标记 和 列标记
    
        for(int i=0; i<N; i++)///第 i 行
        {
            for(int j=0; j<N; j++)
            {
                if(maps[i][j] == '.')
                    NodeInfo[i][j].x = m;
                if(maps[i][j+1] == 'X' || maps[i][j+1] == 0)
                    m ++;
            }
        }
    
        for(int i=0; i<N; i++)///第 i 列
        {
            for(int j=0; j<N; j++)
            {
                if(maps[j][i] == '.')
                    NodeInfo[j][i].y = n;
                if(maps[j+1][i] == 'X' || maps[j+1][i] == 0)
                    n ++;
            }
        }
    
        for(int i=0; i<N; i++)
        {
            for(int j=0; j<N; j++)
            {
                int x = NodeInfo[i][j].x;
                int y = NodeInfo[i][j].y;
    
                if(maps[i][j] == '.')
                    G[x][y] = true;
            }
        }
    }
    
    
    int main()
    {
        while(scanf("%d", &N), N)
        {
    
    
            memset(G, 0, sizeof(G));
            memset(P, -1, sizeof(P));
            memset(maps, 0, sizeof(maps));
    
            for(int i=0; i<N; i++)
                scanf("%s", maps[i]);
    
            MakeMaps();
            int ans = 0;
            for(int i=0; i<m; i++)
            {
                memset(vis, false, sizeof(vis));
                if( Find(i) )
                    ans ++;
            }
            printf("%d
    ", ans);
        }
        return 0;
    }
     
  • 相关阅读:
    ROW_NUMBER() OVER (PARTITION BY yy ORDER BY zz) in Linq
    Oracle-sql分页方法
    Lambda
    ISNULL做简单的显示字段逻辑
    Select2使用方法汇总
    mysqldump 定时备份数据(全量)
    ubuntu16.10下安装erlang和RabbitMQ
    XShell连接本地Ubuntu虚拟机
    Haroopad 安装到 Mac OSX
    Swagger 生成API文档
  • 原文地址:https://www.cnblogs.com/chenchengxun/p/4718571.html
Copyright © 2020-2023  润新知