当前位置: 首页 > news >正文

P1894 [USACO4.2] 完美的牛栏The Perfect Stall

这道题目是经典的二分图最大匹配(Bipartite Matching) 问题。在信奥(OI)中,这是学习图论时必须掌握的基础模板题。


1. 题目分析

我们可以将题目中的信息抽象为一个二分图

  • 左侧集合\(n\) 头奶牛。
  • 右侧集合\(m\) 个牛栏。
  • :如果奶牛 \(i\) 喜欢牛栏 \(j\),则在 \(i\)\(j\) 之间连一条无向边。

题目要求“每个牛栏只能容纳一头奶牛,一头奶牛只能在一个牛栏中产奶”,这正是要求我们在这个二分图中找到最大匹配数(即选出尽可能多的边,使得任意两条边都没有公共端点)。


2. 核心算法:匈牙利算法 (Hungarian Algorithm)

解决二分图最大匹配最常用的算法是匈牙利算法。其核心思想是寻找增广路(Augmenting Path)

算法步骤:

  1. 从第一头奶牛开始,尝试给它安排一个它喜欢的牛栏。
  2. 如果该牛栏还没人(未匹配),直接分配给它。
  3. 如果该牛栏已经被奶牛 \(B\) 占用了,我们就去问奶牛 \(B\):“你能不能换一个你喜欢的其他牛栏?”
    • 如果奶牛 \(B\) 能换到另一个空的或能腾出来的牛栏,那么当前的奶牛就可以拥有这个牛栏。
    • 如果奶牛 \(B\) 实在挪不动,当前奶牛就尝试下一个它喜欢的牛栏。
  4. 重复以上过程,直到所有奶牛都尝试过。

3. C++ 代码实现

这里使用邻接表来存储奶牛的喜好,match 数组记录牛栏当前所属的奶牛。

#include <iostream>
#include <vector>
#include <cstring>using namespace std;const int MAXN = 205; // 奶牛和牛栏的最大数量vector<int> adj[MAXN]; // 邻接表:adj[i] 存储奶牛 i 喜欢的牛栏编号
int match[MAXN];       // match[j] 表示牛栏 j 当前匹配的奶牛编号
bool vis[MAXN];        // vis[j] 在单次 DFS 中记录牛栏 j 是否已被访问过int n, m;// 匈牙利算法的核心:寻找增广路
bool dfs(int u) {for (int v : adj[u]) { // 遍历奶牛 u 喜欢的每一个牛栏 vif (!vis[v]) {vis[v] = true; // 标记牛栏 v 在这一轮匹配中已被考虑// 如果牛栏 v 没有匹配,或者原先匹配牛栏 v 的奶牛可以去找别的牛栏if (match[v] == 0 || dfs(match[v])) {match[v] = u; // 匹配成功,更新牛栏 v 的归属return true;}}}return false;
}int main() {// 快速输入输出优化ios::sync_with_stdio(false);cin.tie(0);if (!(cin >> n >> m)) return 0;for (int i = 1; i <= n; ++i) {int s, stall;cin >> s;while (s--) {cin >> stall;adj[i].push_back(stall);}}int max_matches = 0;for (int i = 1; i <= n; ++i) {memset(vis, false, sizeof(vis)); // 每一头奶牛匹配前,清空访问标记if (dfs(i)) {max_matches++;}}cout << max_matches << endl;return 0;
}

4. 关键点解析

  • vis 数组的作用:在一次 dfs(i) 的递归过程中,vis 确保我们不会陷入死循环(比如奶牛 A 抢奶牛 B 的位子,奶牛 B 又想抢回 A 原有的位子)。每一轮为新奶牛寻找匹配时,vis 都要重置。
  • 时间复杂度\(O(N \cdot E)\),其中 \(N\) 是奶牛数量,\(E\) 是总的喜好边数。对于 \(N, M \le 200\) 的规模,这个算法运行得非常快。
  • 空间复杂度\(O(N + M + E)\)

5. 教学建议

在给学生讲解时,可以把这个过程比作“霸占座位的连锁反应”。

  1. 新同学想坐某个位置。
  2. 位置上有人,就请那个人挪走。
  3. 那个人挪走的前提是,他也能找到(或抢到)新位置。
  4. 如果一连串的挪动都能成功,那么总人数(匹配数)就加 1。
http://www.jsqmd.com/news/432500/

相关文章:

  • Qwen-Image-Layered:重塑图像编辑的“内在可编辑性”
  • 2026年实验室设备厂家推荐:冷水机组/精馏塔领域的实力企业盘点 - 深度智识库
  • Qwen-Image-Layered 实战指南:如何像操作 Photoshop 一样“拆解”与“重组”图像
  • Xbox Game Bar 录制的视频默认保存在哪里以及如何更改?
  • 吊打Transformer!时间序列异常检测新突破!霸榜ICLR 2026
  • 加湿器怎么选不踩坑?2026年五大品牌深度测评与选型指南 - 深度智识库
  • SMV1494,陶瓷突变结变容二极管
  • 金三银四面试突击之Java面试如何确保kafka集群具备高可用性?
  • 一文彻底搞懂Redis分布式锁原理与实现
  • 「权威评测」2026年国内五大玻璃反应釜厂家实力推荐,谁才是靠谱之选? - 深度智识库
  • 域名代购流程是什么?一文讲清完整步骤与关键细节
  • 2026年金三银四面试题100+大全(合适各级Java人员)
  • 计算机专业双非一本学生如何进字节跳动?
  • 除夕夜,我和我的“硅基同事”一起守岁
  • 塑胶跑道领军者:河南赛特体育以科技赋能体育强国梦 - 朴素的承诺
  • Linux系统常用命令格式!
  • 元宵新玩法:和会“动”的AI数字人实时猜灯谜,谜底竟是ta?
  • 监控Linux系统性能的常用命令!
  • 硅PU领航者 筑梦体育强国——河南赛特体育设施工程有限公司的产业深耕之路 - 朴素的承诺
  • 2026年扩散炉供应厂家推荐,前5款高品质扩散炉制造厂家排行榜 - 睿易优选
  • 除湿机怎么选?看准这5大核心要素,2026年高性价比/专业级品牌推荐 - 深度智识库
  • 2026哪家助贷平台放款快?快速到账服务平台盘点 - 品牌排行榜
  • 2026年焊管机/焊管机组/焊管机械/高频焊管设备厂家实力推荐榜:匠心工艺与高效稳定性能深度解析 - 品牌企业推荐师(官方)
  • 网络安全就业领域有哪些?
  • 零基础怎么使用AI写论文?锐智AI一站式搞定论文所有环节 - 资讯焦点
  • 硅PU领航者 筑梦体育强国——河南赛特体育设施工程有限公司赋能全民健身 - 朴素的承诺
  • 机器人初创公司K-Scale Labs倒闭事件反思:从内部见证失败后,COO总结出6条血的教训
  • 中关村清华科技园写字楼租赁 这几家中介公司值得考虑 - 资讯焦点
  • NMN哪个牌子好?2026年NMN十大排名发布:奥本元凭实力上榜 - 资讯焦点
  • 河南赛特体育:人工草坪足球场智造引领者,筑就体育强国梦 - 朴素的承诺