码迷,mamicode.com
首页 > 其他好文 > 详细

POJ2226 Muddy Fields

时间:2018-09-14 17:27:42      阅读:149      评论:0      收藏:0      [点我收藏+]

标签:inline   标记   for   char   int   二分   turn   pre   clu   

原题链接

因为每一块泥地要么被横着的木板盖住,要么被竖着的木板盖住,所以可以转换为二分图最小点覆盖问题。
我们可以先标记出所有连续的行泥地和连续的列泥地。
比如对于原题中的样例,标记后是这样的:
行连续泥地:\(\begin{pmatrix}1 & 0 & 2 & 0 \\ 0 & 3 & 3 & 3 \\ 4 & 4 & 4 & 0 \\ 0 & 0 & 5 & 0 \end{pmatrix}\)

列连续泥地:\(\begin{pmatrix}1 & 0 & 2 & 0 \\ 0 & 3 & 2 & 4 \\ 5 & 3 & 2 & 0 \\ 0 & 0 & 2 & 0 \end{pmatrix}\)
然后对于每一块泥地,在它所在的行连续泥地向列连续泥地连边。
连边后形成的二分图的最小点覆盖即是答案。

#include<cstdio>
#include<cstring>
using namespace std;
const int N = 5010;
const int M = 7e6 + 10;
const int K = 52;
int fi[N], di[M], ne[M], mtc[N], R[K][K], C[K][K], l;
bool v[N], a[K][K];
inline int re()
{
    int x = 0;
    char c = getchar();
    bool p = 0;
    for (; c < '0' || c > '9'; c = getchar())
        p |= c == '-';
    for (; c >= '0' && c <= '9'; c = getchar())
        x = x * 10 + c - '0';
    return p ? -x : x;
}
inline int re_l()
{
    char c = getchar();
    for (; c ^ '.' && c ^ '*'; c = getchar());
    return !(c ^ '.') ? 0 : 1;
}
inline void add(int x, int y)
{
    di[++l] = y;
    ne[l] = fi[x];
    fi[x] = l;
}
bool dfs(int x)
{
    int i, y;
    for (i = fi[x]; i; i = ne[i])
        if (!v[y = di[i]])
        {
            v[y] = 1;
            if (!mtc[y] || dfs(mtc[y]))
            {
                mtc[y] = x;
                return true;
            }
        }
    return false;
}
int main()
{
    int i, j, n, m, ro = 0, co = 0, s = 0;
    n = re();
    m = re();
    for (i = 1; i <= n; i++)
        for (j = 1; j <= m; j++)
        {
            a[i][j] = re_l();
            if (a[i][j])
            {
                R[i][j] = a[i][j - 1] ? R[i][j - 1] : ++ro;
                C[i][j] = a[i - 1][j] ? C[i - 1][j] : ++co;
            }
        }
    for (i = 1; i <= n; i++)
        for (j = 1; j <= m; j++)
            if (a[i][j])
                add(R[i][j], C[i][j] + ro);
    for (i = 1; i <= ro; i++)
    {
        memset(v, 0, sizeof(v));
        if (dfs(i))
            s++;
    }
    printf("%d", s);
    return 0;
}

POJ2226 Muddy Fields

标签:inline   标记   for   char   int   二分   turn   pre   clu   

原文地址:https://www.cnblogs.com/Iowa-Battleship/p/9647436.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!