• HUST 1027 Enemy Target!


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

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

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

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

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

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

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

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

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

    详见北京大学神犇Matrix67的讲解http://blog.csdn.net/niushuai666/article/details/7036897
    #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];
    vector<int>Gl[MAXN];
    vector<int>Gr[MAXN];
    vector<int> ansr;
    vector<int> ansc;
    int flagl[MAXN], flagr[MAXN];
    int flag[MAXN];
    int mat[MAXN][MAXN];
    
    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;
    }
    
    void dfs(int now, int x)
    {
        if (x==0)
        {
            flagl[now] = 1;
            for (int i = 0; i<Gl[now].size(); i++)
                if (flagr[Gl[now][i]] == 0 && cx[now] == Gl[now][i])
                    dfs(Gl[now][i], 1);
    
        }
        else
        {
            flagr[now] = 1;
            for (int i = 0; i<Gr[now].size(); i++)
                if (flagl[Gr[now][i]] == 0 && cy[now] != Gr[now][i])
                    dfs(Gr[now][i], 0);
        }
    }
    
    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++) Gl[i].clear();
            for (int i = 0; i<=COLUMN; i++) Gr[i].clear();
            for (int i = 0; i < ROW; i++)
            for (int j = 0; j < COLUMN; j++)
            if (s[i][j] == '1')
            {
                g[i][j] = 1;
                Gl[i].push_back(j);
                Gr[j].push_back(i);
            }
            nx = ROW;
            ny = COLUMN;
            int ans = MaxMatch();
            if (ans>N)  printf("NOT ENOUGH TANK
    ");
            else
            {
                printf("%d
    ", ans);
    
                memset(flagl, 0, sizeof flagl);
                memset(flagr, 0, sizeof flagr);
                memset(flag, 0, sizeof flag);
                memset(mat, 0, sizeof mat);
                ansr.clear();
                ansc.clear();
    
                for (int i = 0; i<ROW; i++) if (cx[i] != -1) flag[cx[i]] = 1;
                for (int j = 0; j<COLUMN; j++) if (!flag[j]) dfs(j, 1);
    
                for (int i = 0; i<ROW; i++) if (flagl[i]) ansr.push_back(i);
                for (int i = 0; i<COLUMN; i++) if (!flagr[i]) ansc.push_back(i);
    
                printf("ROW:");
                for (int i = 0; i < ansr.size(); i++) printf(" %d", ansr[i]+1);
                printf("
    ");
    
                printf("COLUMN:");
                for (int i = 0; i < ansc.size(); i++) printf(" %d", ansc[i]+1);
                printf("
    ");
    
            }
        }
        return 0;
    }
  • 相关阅读:
    164.Maximum Gap
    163.Missing Ranges
    162.Find Peak Element
    161.One Edit Distance
    160.Intersection of Two Linked Lists
    7.5爬取猫眼Top100电影名单
    7.5文件操作
    7.4文件操作(1)
    7.4一个失败的网易云爬虫,
    7.3数据结构(1)
  • 原文地址:https://www.cnblogs.com/zufezzt/p/5160939.html
Copyright © 2020-2023  润新知