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;
}

posted @ 2016-09-21 19:35  里巴鲁鲁  阅读(131)  评论(0编辑  收藏  举报