zoukankan      html  css  js  c++  java
  • 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;
    }
     
  • 相关阅读:
    Eclipse常用开发插件
    getOutputStream() 的问题
    JSP内置对象之WEB安全性及config对象
    windows开机后键盘失灵(非硬件原因)解决办法
    Eclipse下如何导入jar包
    更改Eclipse下Tomcat的部署目录 ,防止上传的文件是到eclipse的克隆的tomcat上的webapp,而不是tomcat本身的webapp
    大数据的挑战:数据质量和历史偏见
    HR数据分析常用的50个公式
    HR数据分析常用的50个公式
    python中的随机函数random的用法示例
  • 原文地址:https://www.cnblogs.com/chenchengxun/p/4718571.html
Copyright © 2011-2022 走看看