📅  最后修改于: 2023-12-03 15:12:45.813000             🧑  作者: Mango
该题目可以帮助程序员加深对数据结构的理解,以及熟悉C++语言的基本操作和调试技巧。
题目描述:给出n个门,每个门有一把钥匙,编号为1~n。有m个人,每个人有各自的一组钥匙,若有门的钥匙和他携带的钥匙相同,则可以打开该门。现在要求所有人都需要走进编号为1的门,求所有人必须要走过几扇门(包括1号门)。
输入格式:第一行输入n和m,接下来m行每行输入一个人所带的钥匙的个数以及对应的钥匙编号。 输出格式:输出所有人必须要走过的最小的门的数量。
本题可以通过建立一个钥匙与门之间的映射关系,建立一个map或unorder_map, 将每个人所拥有的钥匙和对应的门的关系存储下来。
接下来依次遍历每个人所拥有的钥匙,将每个钥匙对应的门的编号标记为已开启状态,再对所有门进行广度优先遍历,寻找可达的门并进行标记。最终如果1号门被标记为已经开启,则所有人一定可以走到1号门。最后输出所有已经被标记过的门的数量即可。
#include<iostream>
#include<map>
#include<queue>
using namespace std;
const int N = 1e5 + 10;
int n, m;
map<int, vector<int>> key_map;
queue<int> q;
int used[N];
int bfs() {
int res = 0;
q.push(1);
used[1] = 1;
while (q.size()) {
int size = q.size();
res++;
while (size--) {
int t = q.front();
q.pop();
if (key_map.count(t)) {
for (auto door_id : key_map[t]) {
if (!used[door_id]) {
q.push(door_id);
used[door_id] = 1;
}
}
key_map.erase(t);
}
}
}
return res;
}
int main() {
cin >> n >> m;
while (m--) {
int k;
cin >> k;
while (k--) {
int x;
cin >> x;
key_map[x].push_back(n + m + 1);
}
}
int res = bfs();
cout << (used[1] ? res : -1);
return 0;
}
代码中我们使用了C++标准库中的map,用来存储钥匙与门之间的映射关系,使得代码实现及其简便和易读。在搜索时,我们使用了BFS来搜索所有可达的门,用队列来管理搜索过程中未被扩展节点的状态,并用used数组来标记是否访问过相关节点。最终输出所有已经被标记过的门的数量即可。
返回的markdown格式如下:
# 门|门 CS 1996 |第54题介绍
该题目可以帮助程序员加深对数据结构的理解,以及熟悉C++语言的基本操作和调试技巧。
## 题目说明
题目描述:给出n个门,每个门有一把钥匙,编号为1~n。有m个人,每个人有各自的一组钥匙,若有门的钥匙和他携带的钥匙相同,则可以打开该门。现在要求所有人都需要走进编号为1的门,求所有人必须要走过几扇门(包括1号门)。
输入格式:第一行输入n和m,接下来m行每行输入一个人所带的钥匙的个数以及对应的钥匙编号。
输出格式:输出所有人必须要走过的最小的门的数量。
## 解题思路
本题可以通过建立一个钥匙与门之间的映射关系,建立一个map或unorder_map, 将每个人所拥有的钥匙和对应的门的关系存储下来。
接下来依次遍历每个人所拥有的钥匙,将每个钥匙对应的门的编号标记为已开启状态,再对所有门进行广度优先遍历,寻找可达的门并进行标记。最终如果1号门被标记为已经开启,则所有人一定可以走到1号门。最后输出所有已经被标记过的门的数量即可。
## 代码示例
```c++
#include<iostream>
#include<map>
#include<queue>
using namespace std;
const int N = 1e5 + 10;
int n, m;
map<int, vector<int>> key_map;
queue<int> q;
int used[N];
int bfs() {
int res = 0;
q.push(1);
used[1] = 1;
while (q.size()) {
int size = q.size();
res++;
while (size--) {
int t = q.front();
q.pop();
if (key_map.count(t)) {
for (auto door_id : key_map[t]) {
if (!used[door_id]) {
q.push(door_id);
used[door_id] = 1;
}
}
key_map.erase(t);
}
}
}
return res;
}
int main() {
cin >> n >> m;
while (m--) {
int k;
cin >> k;
while (k--) {
int x;
cin >> x;
key_map[x].push_back(n + m + 1);
}
}
int res = bfs();
cout << (used[1] ? res : -1);
return 0;
}
代码中我们使用了C++标准库中的map,用来存储钥匙与门之间的映射关系,使得代码实现及其简便和易读。在搜索时,我们使用了BFS来搜索所有可达的门,用队列来管理搜索过程中未被扩展节点的状态,并用used数组来标记是否访问过相关节点。最终输出所有已经被标记过的门的数量即可。