1. 程式人生 > >CCF-201403-4-無線網路

CCF-201403-4-無線網路

題目大意:
在這一堆路由器中找出第一個路由器到第二個路由器經過的最少中轉路由器數,最少次數問題。用廣搜bfs,一層層搜,哪層搜到就返回層數 - 1,每層走的時候計搜到的新增路由器數,當經過的新增路由器數小於等於k時才入列。

注意:

  1. 建立鄰接表時,計算結點兩兩之間的距離,小於等於r就建立這兩個結點的連線。
  2. bfs的邏輯是一層層的進行,每層的裡面的元素是一個列表 [ node 結點,count 遍歷到新增結點的個數 ]
  3. 鄰接表長度是n+m, n之後的結點是新增結點,所以通過結點標號是否 》=n 就可以判斷是否為新增結點。
  4. 這裡我把原來的n個結點和新增的m個結點一起搜。搜到新增結點就計數加1,再入列。

python程式碼(100)

def getDist(n1, n2):
    return (abs(n1[0] - n2[0]) ** 2 + abs(n1[1] - n2[1]) ** 2) ** 0.5


# 廣搜,放回經過的結點總數
def bfs(start, end, graph, k, m):
    n = len(graph)
    queue = []
    queue.append([start, 0])  # 列表第二個元素用來計新增的結點數
    visited = [False for _ in graph]
    layer = 0
    # 每次遍歷一層,生成下一層,迭代更新列表
    while True:
        temque = []  # 下一層
        for popnode in queue:  # 遍歷這一層
            if popnode[0] == end:  # 如果走到end就返回層數
                return layer - 1

            # 生成下一層
            for node in graph[popnode[0]]:
                # 新增結點數沒超過k的才入列
                if not visited[node] and popnode[1] <= k:
                    count = popnode[1]
                    if node >= n - m:
                        count += 1
                    temque.append([node, count])
                    visited[node] = True
        queue = temque
        layer += 1


n, m, k, r = map(int, input().split())
nodes = []
graph = [[] for _ in range(n + m)]

# 存結點
for i in range(n + m):
    nodes.append([int(v) for v in input().split()])

# 處理結點,算結點間的距離,距離在r之間就有連線
for i in range(len(nodes) - 1):
    for j in range(i + 1, len(nodes)):
        if getDist(nodes[i], nodes[j]) <= r:
            graph[i].append(j)
            graph[j].append(i)

# 從第一個結點(0)開始廣搜,搜到第二個結點(1)就停,期間計數經過多少個結點。
print(bfs(0, 1, graph, k, m))

# 5 3 1 3
# 0 0
# 5 5
# 0 3
# 0 5
# 3 5
# 3 3
# 4 4
# 3 0