zoukankan      html  css  js  c++  java
  • HDU 1045 Fire Net 二分图匹配 经典建图方法

    HDU 1045 Fire Net 二分图匹配 经典建图方法

    题目来源:

    题意:

    找到图中可以安放堡垒并不会互相攻击的位置方案数。(堡垒向4个方向发射子弹,并且墙可以挡下子弹)

    题解:

    分析:

    要达到题目的要求,只要找到可以满足覆盖所有的空白的放置方案即可。那么便可以将题目转变为二分图最大匹配。

    主要解题方案:二分图最大匹配+(一行变多行,一列变多列建图方法)

    当然,这题数据不大,也可以使用DFS暴力搜一遍过去。

    参考资料:百度文库

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cstdio>
    #include <cmath>
    typedef long long ll;
    typedef unsigned long long ull;
    using namespace std;
    char mp[50][50];
    int n;
    int row[50][50],col[50][50],r[50],c[50];
    int cnt_c,cnt_r;
    bool G[50][50];
    bool vi[50];
    
    int dfs(int x)
    {
        for(int i=0;i<cnt_c;i++)
        {
            if(G[x][i] && !vi[i])
            {
                vi[i]=1;
                if(c[i]==-1||dfs(c[i]))
                {
                    c[i]=x;
                    r[x]=i;
                    return 1;
                }
            }
        }
        return 0;
    }
    
    int match()    //匈牙利算法
    {
        int ans=0;
        memset(r,-1,sizeof(r));
        memset(c,-1,sizeof(c));
        for(int i=0;i<cnt_r;i++)
            if(r[i]==-1)
            {
                memset(vi,0,sizeof(vi));
                ans+=dfs(i);
            }
        return ans;
    }
    
    int main()
    {
    #ifndef ONLINE_JUDGE
       // freopen("test.in","r",stdin);
        //freopen("test.out","w",stdout);
    #endif
        while(cin >> n && n)
        {
            memset(row,-1,sizeof(row));
            memset(col,-1,sizeof(col));
            cnt_c=cnt_r=0;
            for(int i=0;i<n;i++)
                cin >> mp[i];
            for(int i=0;i<n;i++)    //建图过程1
            {
                for(int j=0;j<n;j++)
                {
                    if(mp[i][j] == '.' && row[i][j]==-1)
                    {
                        for(int k=j;mp[i][k]=='.'&& k<n;k++)
                            row[i][k]=cnt_r;
                        cnt_r++;
                    }
                    if(mp[j][i]=='.' && col[j][i]==-1)
                    {
                        for(int k=j;mp[k][i]=='.'&& k<n;k++)
                            col[k][i]=cnt_c;
                        cnt_c++;
                    }
                }
            }
            memset(G,0,sizeof(G));
            for(int i=0;i<n;i++)    //建图过程2
                for(int j=0;j<n;j++)
                    if(mp[i][j]=='.')
                        G[row[i][j]][col[i][j]]=1;
            cout << match() << endl;
        }
        return 0;
    }
    
    
  • 相关阅读:
    json转实体,json转List实体,json转泛型实体
    java使用google开源工具实现图片压缩
    SpringBoot的文件下载
    SpringBoot(三):文件下载
    java transient关键字作用,使用场景。
    ApplicationContextAware接口的作用
    JAVA中STATIC{}语句块详解
    RGB转灰度图的几种算法
    JavaScript系列文章:谈谈let和const
    mybatis中的#{}和${}区别
  • 原文地址:https://www.cnblogs.com/Combustible-ice/p/5893880.html
Copyright © 2011-2022 走看看