转化为最小可相交路径覆盖问题

#include <cstdio>
#include <vector>
#include <bitset>
#include <functional>
using namespace std;

int n, m, ans, a[21][21], mp[21][21][21][21];
char c;
bitset<404> vis;

int main()
{
    scanf("%d%d", &n, &m);
    vector<vector<int>> g(n * m + 1);
    vector<int> f(n * m + 1, 0);

    for (int i = 1; i <= n; ++i)
    {
        for (int j = 1; j <= m; ++j)
        {
            scanf(" %c", &c);
            ans += (c - '0');
            a[i][j] = c - '0';
            if(a[i][j]){
                if(a[i-1][j])mp[i-1][j][i][j]=1;
                if(a[i][j-1])mp[i][j-1][i][j]=1;
            }
        }
    }

    for(int kk=1;kk<=n;++kk){
        for(int k=1;k<=m;++k){
            for(int ii=1;ii<=n;++ii){
                for(int i=1;i<=m;++i){
                    for(int jj=1;jj<=n;++jj){
                        for(int j=1;j<=m;++j){
                            if(ii!=jj&&i!=j){
                                if(mp[ii][i][kk][k]&&mp[kk][k][jj][j]){
                                    mp[ii][i][jj][j]=1;
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    for(int i=1;i<=n;++i){
        for(int ii=1;ii<=m;++ii){
            for(int j=1;j<=n;++j){
                for(int jj=1;jj<=m;++jj){
                    if(mp[i][ii][j][jj]){
                        g[(i-1)*m+ii].push_back((j-1)*m+jj);
                    }
                }
            }
        }
    }

    function<bool(int)> ck = [&](int x) -> bool
    {
        for (vector<int>::iterator it = g[x].begin(); it != g[x].end(); ++it)
        {
            if (!vis[*it])
            {
                vis[*it] = 1;
                if (!f[*it] || ck( f[*it]))
                {
                    f[*it] = x;
                    return true;
                }
            }
        }
        return false;
    };
    for (int i = 1; i <= n*m; ++i)
    {
        vis.reset();
        if (ck(i))
        {
            ans -= 1;
        }
    }

    printf("%d", ans);
}
此文章已被阅读次数:正在加载...更新于