AtCoder Beginner Contest 168 D题,https://atcoder.jp/contests/abc168/tasks/abc168_d。
There is a cave.
The cave has N rooms and M passages. The rooms are numbered 1 to N, and the passages are numbered 1 to M. Passage ii connects Room Ai and Room Bi bidirectionally. One can travel between any two rooms by traversing passages. Room 1 is a special room with an entrance from the outside.
It is dark in the cave, so we have decided to place a signpost in each room except Room 1. The signpost in each room will point to one of the rooms directly connected to that room with a passage.
Since it is dangerous in the cave, our objective is to satisfy the condition below for each room except Room 1.
Determine whether there is a way to place signposts satisfying our objective, and print one such way if it exists.
Input is given from Standard Input in the following format:
N M
A1 B1
:
AM BM
If there is no way to place signposts satisfying the objective, print No
.
Otherwise, print N lines. The first line should contain Yes
, and the i-th line (2 ≤ i ≤ N) should contain the integer representing the room indicated by the signpost in Room i.
4 4
1 2
2 3
3 4
4 2
Yes
1
2
2
If we place the signposts as described in the sample output, the following happens:
Thus, the objective is satisfied.
6 9
3 4
6 1
2 4
5 3
4 6
1 5
6 2
4 5
5 6
Yes
6
5
5
1
1
If there are multiple solutions, any of them will be accepted.
山洞里有 N 个房间,有 M 个通道。房间编号从 1 到 N,通道编号从 1 到M。通道 i 双向连接房间 Ai 通向 Bi。1 号房是总出入口。我们需要在每个房间(除了第 1 个房间)放置一个路标,该路标指明通过通道连接到另外一个房间号码。问我们是否存在解决方案。
其实到了这里,我们应该比较明确这是一个搜索问题,也就是最短路径问题,那么经验告诉我们,最好的方法是 BFS。本题不能使用 DFS,因为有可能会出现环。有人要问为什么啊?没什么内核,就是题目做多了,看到题目的意思就知道可能的方法。如下面马上要分析的样例数据1,我们可以看到一个环,因此使用 DFS 是不适合的。而且,我们看到原题中出现 minimum 的字样,就是说最短路径嘛,哪肯定是 BFS。
有 4 个房间,4 个通道。第 1 号通道连接房间 1 和 2;第 2 号通道连接房间 2 和 3;第 3 号通道连接房间 3 和 4;第 4 号通道连接房间 4 和 2。这样我们可以绘制出如下的图。
下面我们从第 2 号房间开始,逐一遍历。
2 号房间要到 1号房间。我们可以看出最短的路径应该是 2->1,,因此我们只需要在 2 号房间的路标上写上 1 即可。
3 号房间要到 1号房间。我们可以看出最短的路径应该是 3->2->1,这样我们只需要在 3 号房间的路标上写上 2 即可。
4 号房间要到 1号房间。我们可以看出最短的路径应该是 4->2->1,这样我们只需要在 4 号房间的路标上写上 2 即可。
有 6 个房间,9 个通道。第 1 号通道连接房间 3 和 4;第 2 号通道连接房间 6 和 1;第 3 号通道连接房间 2 和 4;第 4 号通道连接房间 5 和 3;第 5 号通道连接房间 4 和 6;第 6 号通道连接房间 1 和 5;第 7 号通道连接房间 6 和 2;第 8 号通道连接房间 4 和 5;第 9 号通道连接房间 5 和 9。这样我们可以绘制出如下的图。
下面我们从第 2 号房间开始,逐一遍历。
2 号房间要到 1号房间。我们可以看出最短的路径应该是 2->6->1,因此我们只需要在 2 号房间的路标上写上 6 即可。
3 号房间要到 1号房间。我们可以看出最短的路径应该是 3->5->1,这样我们只需要在 3 号房间的路标上写上 5 即可。
4 号房间要到 1号房间。我们可以看出最短的路径应该是 4->5->1 或者 4->6->1,这样我们只需要在 4 号房间的路标上写上 5 或者 6 即可。
5 号房间要到 1号房间。我们可以看出最短的路径应该是 5->1,这样我们只需要在 5 号房间的路标上写上 1 即可。
6 号房间要到 1号房间。我们可以看出最短的路径应该是 6->1,这样我们只需要在 6 号房间的路标上写上 1 即可。
N 的最大值是 1e5。
M 的最大值是 2e5。
Ai 和 Bi 的最大值不会超过 N。
所以本题需要定义一个 2e5 大小的数组,数据类型使用 int 足够。
没什么特殊的地方,直接套用 BFS 模板即可。核心就是从第 1 号房间出发,看一下能走到哪些房间,并记录下相连房间的连接记录。BFS 遍历完成后,从 2 号房间开始查看是否所有的房间都有连接性。
#include
using namespace std;
const int MAXN = 2e5+10;
vector datas[MAXN];//通道关系
int ans[MAXN];//保存最近的房间号
void bfs() {
queue q;
q.push(1);
ans[1] = 1;
while (!q.empty()) {
int u = q.front();
q.pop();
for (auto v:datas[u]) {
if (0==ans[v]) {
q.push(v);
ans[v] = u;
}
}
}
}
int main() {
int n,m;
scanf("%d%d", &n, &m);
for (int i=0; i
P.S.
这里使用了 auto 变量,这个在 NOIP 是不支持的。