运行要求
运行时间限制: 2sec
内存限制: 1024MB
未经允许,不得许转载
原题链接
题目
有一个地方,有一个洞穴
洞穴里面有N个房间和M条路。房间的编号是1到N,路的编号是1到M。路i连结着房间Ai,Bi,使得Ai和Bi能够双向通行。任意两个房间之间都有或多或少的路可以通行。房间1是洞穴的出口,属于特别房间。
洞穴很暗,对于房间1以外的房间。每个房间设置一个路标。这个路标指向连结着这个房间的路的其中一条路所通向的另外一端的房间。
因为洞穴很危险,所以,对于房间1以外的房间,需要满足下面的条件。
- 重这个房间出发,【按照目前房间的唯一一个路标,走向路标指向的房间】,按着如此操作重复,知道以最近的路线走到房间1
判断能不能达到目标,如果可以,输出一种安排路标的方案。
输入前提条件
- 所有的输入均为整数
- 2 <=N <= 10^5
- 1 <=M <= 2*10^5
- 1 <=Ai,Bi<=N (1<=i<=M)
- Ai != Bi(1<=i<=M)
- 任意两个房间之间都存在通道把它们连结在一起
输入
输入按照以下形式标准输入
N M
A1 B1
A2 B2
.
.
.
AM BM
输出
如果满足条件的方案不存在的话,输出"No"
如果存在的话,输出N行。第1行输出"Yes",i(2<=i<=N),输出房间i的路标指向的另外一个房间的编号
例1
输入
4 4
1 2
2 3
3 4
4 2
输出
Yes
1
2
2
就像输出所显示的那样去布置路标
从房间2出发 2->1 移动1次,这样是最小的
从房间3出发 3->2->1 移动2次,这样是最小的
从房间4出发 4->2->1 移动2次,这样是最小的
因此,按照输出所示的路标布置方案是最优方案
例2
输入
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
答案有多种,输出哪一种都可以
读懂题目
简单吧例2画一下
输入
输出
解题思路
先简单地说一下思路
题目说过了,每两个房间之间都会有通道,所以所有的房间都可以通过通道连到房间1
假如房间i的深度是Li,那么房间j的路标应该是指向深度为Li-1的房间才是最近的
用bfs去遍历
代码
N, M = map(int, input().split())
ARR = []
for i in range(M):
ARR.append(list(map(int, input().split())))
from collections import deque
def prepare(n, m, arr):
nodes = [[] for i in range(n)]
nodeStates = [-1 for i in range(n)]
prevs = [-1 for i in range(n)]
for i in range(m):
startNode = arr[i][0] - 1
endNode = arr[i][1] - 1
nodes[startNode].append(endNode)
nodes[endNode].append(startNode)
return nodes, nodeStates, prevs
nodes, nodeStates, prevs = prepare(N, M, ARR)
def bfs(nodes, nodeStates, prevs, n):
q = deque()
q.append({'prev': -1, 'to': 0})
while len(q) > 0:
first = q.popleft()
currentNode = first['to']
previousNode = first['prev']
if nodeStates[currentNode] != -1:
continue
prevs[currentNode] = previousNode
childNodes = nodes[currentNode]
nodeStates[currentNode] = 1
for childNode in childNodes:
q.append({'prev': currentNode, 'to': childNode})
print("Yes")
for i in range(1, n):
print(prevs[i] + 1)
bfs(nodes, nodeStates, prevs, N)
总结
这道题考察对bfs的理解
※ 另外,我会在我的微信个人订阅号上推出一些文章,欢迎关注
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。