题目大意:
在这一堆路由器中找出第一个路由器到第二个路由器经过的最少中转路由器数,最少次数问题。用广搜bfs,一层层搜,哪层搜到就返回层数 - 1,每层走的时候计搜到的新增路由器数,当经过的新增路由器数小于等于k时才入列。
注意:
- 建立邻接表时,计算结点两两之间的距离,小于等于r就建立这两个结点的连接。
- bfs,队列里的每个元素是一个列表 [ node 结点,step步数(层数) ,k_count 遍历到新增结点的个数 ]
- 邻接表长度是n+m, n以及n之后的结点是新增结点,所以通过结点标号是否 >=n 就可以判断是否为新增结点。
- bfs的时候,如果搜到新增结点个数超过k就不入队。
python代码(100)
def getDist(x1, y1, x2, y2):
return (abs(x1 - x2) ** 2 + abs(y1 - y2) ** 2) ** 0.5
def bfs():
queue = [[0, 0, 0]] # [当前点,步数,新增类型的结点个数]
vis = [False] * len(graph)
vis[0] = True
while queue:
node, step, k_count = queue.pop(0)
# 搜到点2就返回层数减1
if node == 1:
return step - 1
# 找邻点,如果新增类型的结点 超过k就不入队
for nd in graph[node]:
# 遇到新增类型的结点,计数加一,标号是n以及之后的就是新增结点
k_count_tem = (k_count + 1) if nd >= n else k_count
if not vis[nd] and k_count_tem <= k:
queue.append([nd, step + 1, k_count_tem])
vis[nd] = True
n, m, k, r = map(int, input().split())
graph = [[] for _ in range(n + m)]
nodes = []
for i in range(n + m):
nodes.append([int(e) for e in input().split()])
# 整理点,两点距离<=r的连线,构图
for i in range(len(nodes) - 1):
for j in range(i + 1, len(nodes)):
x1, y1 = nodes[i]
x2, y2 = nodes[j]
if getDist(x1, y1, x2, y2) <= r:
graph[i].append(j)
graph[j].append(i)
print(bfs())