现在的位置: 首页 > 综合 > 正文

hdu 5093 Battle ships(最大二分匹配)

2018年04月03日 ⁄ 综合 ⁄ 共 1326字 ⁄ 字号 评论关闭

hdu 5093 Battle ships

图中有三类点:水、浮冰、冰山

船与其他在同一横纵轴内的船无法同时存在除非被冰山隔开

船只能被放置在水中

求最多能放多少船


对于每块水域只有放或不放置船两种选择,因此很容易联想到最大二分匹配。由于任何在同一线上的水域只能放一艘船,可以视作一个整体。所以对于每块水域,横向和纵向有交点则连线。


#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;
const int MAXN = 51, MAXM = MAXN*MAXN;
char mp[MAXN][MAXN], ap[MAXN][MAXN];
int visr[MAXN][MAXN], visc[MAXN][MAXN], cntr, cntc;
int n, m;
vector<int> vc[MAXM];
int mb[MAXM], vis[MAXM];
void init()
{
    memset(visc, 0, sizeof visc);
    memset(visr, 0, sizeof visr);
    cntr = cntc = 0;
    for (int i = 0; i< MAXM; ++i) vc[i].clear();
}
int dfs(int a)
{
    for (int i = 0, j = vc[a].size(); i<j ; ++i)
    {
        int v = vc[a][i];
        if (!vis[v])
        {
            vis[v] = 1;
            if (!mb[v] || dfs(mb[v]))
            {
                mb[v] = a;
                return 1;
            }
        }
    }
    return 0;
}
int hungary(int a)
{
    int cnt = 0;
    memset(mb, 0, sizeof mb);
    for (int i = 1; i<= a; ++i)
    {
        memset(vis, 0, sizeof vis);
        cnt += dfs(i);
    }
    return cnt;
}
int main()
{
#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
#endif // ONLINE_JUDGE
    int t;
    scanf("%d", &t);
    while (t--)
    {
        init();
        scanf("%d%d", &n, &m);
        for (int i = 0; i< n; ++i)
            scanf("%s", mp[i]);
        for (int i = 0; i< n; ++i)
        {
            for (int j = 0; j< m; ++j)
            {
                if (mp[i][j] == '*' && !visr[i][j])
                {
                    ++cntr;
                    for (int k = j; k< m && mp[i][k]!='#'; ++k)
                    {
                        if (mp[i][k] == 'o') continue;
                        visr[i][k] = cntr;
                    }
                }
            }
        }
        cntc = cntr;
        for (int j = 0; j< m; ++j)
        {
            for (int i = 0; i< n; ++i)
            {
                if (mp[i][j] == '*' && !visc[i][j])
                {
                    ++cntc;
                    for (int k = i; k< n && mp[k][j]!='#'; ++k)
                    {
                        visc[k][j] = cntc;
                        if (visr[k][j])
                            vc[visr[k][j]].push_back(cntc);
                    }
                }
            }
        }
        printf("%d\n", hungary(cntr));
    }
    return 0;
}


抱歉!评论已关闭.