Plug It In Gym - 101873F (匈牙利算法 + 增广路)

原题:

Plug It In Gym - 101873F (匈牙利算法 + 增广路)_第1张图片

题意:

有m个插座,n个电器,每个插座最多可连接一个电器。另外有一个插板,可以使得一个插座连接三个电器,问最大匹配数是多少。

题解:

匈牙利算法模板题,这是我之前写过的一道用匈牙利算法解决的题HDU 2063 过山车,先保存不用插板的最大匹配,再枚举每个插座是否还存在增广路,求出最大匹配数。

代码:
#include
using namespace std;
#define mem(a) memset(a, 0, sizeof(a))
#define _for(i, n) for(int i=1; i<=n; i++)
#define ll long long

const int maxn = 1510;
int g[maxn][maxn], linker[maxn], match[maxn];
bool used[maxn];
int n, m, k;

int dfs(int l)
{
    _for(i, m)
    {
        if(g[l][i] == 1 && used[i] == 0)
        {
            used[i] = 1;
            if(linker[i] == -1 || dfs(linker[i]))
            {
                linker[i] = l;
                return 1;
            }
        }
    }
    return 0;
}

int hungary()
{
    memset(linker, -1, sizeof(linker));
    int ans = 0;
    _for(i, n)
    {
        mem(used);
        if(dfs(i)) ans++;
    }
    return ans;
}
int main()
{
    int n, m, k;
    while(scanf("%d%d%d", &n, &m, &k) == 3)
    {
        mem(g);
        int u, v;
        _for(i, k)
        {
            scanf("%d%d", &u, &v);
            g[u][v] = 1;
        }
        int ans = 0, maxx = 0, x=0;
        ans = hungary();
        cout << ans << endl;
        _for(i, n)
        {
            x=0;
            _for(j, m) match[j] = linker[j];
            int s = 2;
            _for(j, s)
            {
                mem(used);
                if(dfs(i)) x++;
            }
            maxx = max(maxx, x);
            _for(j, m) linker[j] = match[j];
        }
        printf("%d\n", ans + maxx);
    }
    return 0;
}


你可能感兴趣的:(二分图匹配相关)