HUST 1027 Enemy Target!

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HUST 1027 Enemy Target!相关的知识,希望对你有一定的参考价值。

求二分图的最小点覆盖集,并输出

对于每一个a[i][j]=1,我们从行i-->列j建立一条边

显然,这张图是一张二分图。左边的节点代表删除哪一行,右边的节点代表删除哪一列。中间的边代表所有a[i][j]为1的点。

现在,我们需要做的事情就是找出最少的点,使这些点覆盖住所有的边(即删去哪几行哪几列,没有士兵)

最少的点,使这些点覆盖住所有的边   这个东西是最小点覆盖集。

对于一张二分图来说,在数量上,最小点覆盖集=最大匹配

如果 最大匹配>坦克数量,那么输出无解

剩下的情况就是有解了,如何寻找解?这问题困扰了我很久......最后还是看了别人的博客。

此外,这题目点最多有2000个,为什么匈牙利算法可以AC......不是o(n^3)效率的吗......

得到匹配结果之后,构造最小点覆盖集的方法:
对于一条边i-j,若不选i就是选j,是吧?做完最大匹配后,我们查没一条边,若link[j]==-1,表明j没有选,那么我们就选i,选完row后,再来看列的,对于一条边i-j,若i选了,就不选j,若i没有选,就选j。
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<algorithm>
using namespace std;

const int MAXN = 1000 + 10;
int nx, ny;
int g[MAXN][MAXN];
int cx[MAXN], cy[MAXN];
int mk[MAXN];
int ROW, COLUMN, N;
char s[MAXN][MAXN];
int flagr[MAXN];
int flagc[MAXN];
vector<int> ansr;
vector<int> ansc;

int path(int u)
{
    for (int v = 0; v<ny; v++)
    {
        if (g[u][v] && !mk[v])
        {
            mk[v] = 1;
            if (cy[v] == -1 || path(cy[v]))
            {
                cx[u] = v;
                cy[v] = u;
                return 1;
            }
        }
    }
    return 0;
}

int MaxMatch()
{
    int res = 0;
    memset(cx, -1, sizeof(cx));
    memset(cy, -1, sizeof(cy));
    for (int i = 0; i<nx; i++)
    {
        if (cx[i] == -1)
        {
            memset(mk, 0, sizeof(mk));
            res = res + path(i);
        }
    }
    return res;
}

int main()
{
    while (~scanf("%d%d%d", &ROW, &COLUMN, &N))
    {
        for (int i = 0; i < ROW; i++) scanf("%s", s[i]);
        memset(g, 0, sizeof g);
        for (int i = 0; i < ROW; i++)
        for (int j = 0; j < COLUMN; j++)
        if (s[i][j] == 1)
            g[i][j] = 1;
        nx = ROW;
        ny = COLUMN;
        int ans = MaxMatch();
        if (ans>N)  printf("NOT ENOUGH TANK\n");
        else
        {
            printf("%d\n", ans);
            memset(flagr, 0, sizeof flagr);
            memset(flagc, 0, sizeof flagc);

            for (int i = 0; i < ROW; i++)
            {
                for (int j = 0; j < COLUMN; j++)
                {
                    if (g[i][j])
                    {
                        if (cy[j] == -1)
                        {
                            flagr[i] = 1;
                        }
                    }
                }
            }
            for (int i = 0; i < ROW; i++)
            {
                for (int j = 0; j < COLUMN; j++)
                {
                    if (g[i][j])
                    {
                        if (flagr[i] == 1){}
                        else flagc[j] = 1;
                    }
                }
            }
            
            for (int i = 0; i < nx; i++) if (flagr[i]) ansr.push_back(i + 1);
            for (int i = 0; i < ny; i++) if (flagc[i]) ansc.push_back(i + 1);

            printf("ROW:");
            for (int i = 0; i < ansr.size(); i++)
                printf(" %d", ansr[i]);
            printf("\n");
            
            printf("COLUMN:");
            for (int i = 0; i < ansc.size(); i++)
                printf(" %d", ansc[i]);
            printf("\n");
        }
    }
    return 0;
}

 

以上是关于HUST 1027 Enemy Target!的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode Bomb Enemy

碰撞自动攻击

java Enemy.java

Leetcode: Bomb Enemy

Bomb Enemy -- LeetCode

361. Bomb Enemy