(二分图匹配)棋盘游戏

http://acm.hdu.edu.cn/showproblem.php?pid=1281

题意为nxm的地图上给出k个车,问图中能存在的最多马个数(不能同行同列),且其中的格子(若不放置车,则会导致能放置的车个数减少)的个数。
求出行列最大匹配, 枚举每个可放置车的格子,若取消该格子会导致最大匹配数减少,则计数+1

#include <bits/stdc++.h>
using namespace std;
const int maxn = 100 + 5;
bool path[maxn][maxn];
int link[maxn], vis[maxn];
bool dfs(int u, int m) {
    for(int v = 1; v <= m; ++v) {
        if(!vis[v] && path[u][v]) {
            vis[v] = 1;
            if(link[v] == -1 || dfs(link[v], m)) {
                link[v] = u;
                return true;
            }
        }
    }
    return false;
}
int max_match(int n, int m) {
    int res = 0;
    memset(link, -1, sizeof(link));
    for(int i = 1; i <= n; ++i) {
        memset(vis, 0, sizeof(vis));
        if(dfs(i, m)) res++;
    }
    return res;
}
pair<int, int> arr[maxn * maxn];
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);

    int n, m, K, cas = 1;
    while(cin >> n >> m >> K) {
        int x, y;
        for(int i = 1; i <= n; ++i)
            for(int j = 1; j <= m; ++j)
                path[i][j] = false;
        for(int i = 0; i < K; ++i) {
            cin >> arr[i].first >> arr[i].second;
            path[arr[i].first][arr[i].second] = true;
        }
        int ans = max_match(n, m), cnt = 0;
        for(int i = 0; i < K; ++i) {
            path[arr[i].first][arr[i].second] = false;
            if(max_match(n, m) < ans) cnt++;
            path[arr[i].first][arr[i].second] = true;
        }
        cout << "Board " << cas++ << " have " << cnt << " important blanks for " << ans << " chessmen." << endl;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值