0x68 - C题:車的放置
链接:https://ac.nowcoder.com/acm/contest/1062/C
题目描述
给定一个N行M列的棋盘,已知某些格子禁止放置。
问棋盘上最多能放多少个不能互相攻击的車。
車放在格子里,攻击范围与中国象棋的“車”一致。
输入描述:
第一行包含三个整数N,M,T,其中T表示禁止放置的格子的数量。
接下来T行每行包含两个整数x和y,表示位于第x行第y列的格子禁止放置,行列数从1开始。
输出描述:
输出一个整数,表示结果。
示例1
输入
8 8 0
输出
8
思路
“1要素”:
每行、每列只能放1个车(不然就能互相攻击到)。某个格子
因此,我们可以把行、列看作节点,一共
“0要素”:
每个車显然不能既在第
因此,刚才构建的无向图是二分图,我们可以把N个“行节点”作为左部,M个列节点”作为右部。
更在不能互相攻击的前提下放置的车最多,就是求上述分图的最大匹配,时间复杂度为
AC代码
#include<bits/stdc++.h>
using namespace std;
int n, m, t, f[210], b[210], ans;
bool a[210][210], v[210];
bool dfs(int x) {
for (int i = 1; i <= m; ++i) {
if (v[i] || a[x][i])continue;
v[i] = 1;
if (f[i] == 0 || dfs(f[i])) {
f[i] = x; return true;
}
}
return false;
}
int main() {
//freopen("in.txt", "r", stdin);
ios::sync_with_stdio(false), cin.tie(0);
cin >> n >> m >> t;
for (int j = 1; j <= t; ++j) {
int x, y; cin >> x >> y;
a[x][y] = 1;
}
for (int i = 1; i <= n; ++i) {
memset(v, 0, sizeof v);
if (dfs(i))++ans;
}
cout << ans << endl;
}
一些匹配方法:
完备匹配:
给定一张二分图,其左部、右部点数相同,均为
条匹配边,则称该二分图具有完备匹配。
多重匹配:
给定一张包含
当
多重匹配一般有 四种解决方案:
1.拆点。把第
图中的每条边
2.如果所有的
直接在匈牙利算法中让每个左部节点执行
3.在第2种方案中,当然也可以交换左右两部,设“右部”是多重的,修改匈牙利算法的实现,让右部
节点可以匹配
4.网络流。这是最一般也是最高效的解决方法。但博主尚未学习(可能以后会补上)。
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· Obsidian + DeepSeek:免费 AI 助力你的知识管理,让你的笔记飞起来!
· 分享4款.NET开源、免费、实用的商城系统
· 解决跨域问题的这6种方案,真香!
· 一套基于 Material Design 规范实现的 Blazor 和 Razor 通用组件库
· 5. Nginx 负载均衡配置案例(附有详细截图说明++)