ccf 2015123 无线网络 100分(python实现)

问题描述
试题编号: 201403-4
试题名称: 无线网络
时间限制: 1.0s
内存限制: 256.0MB
问题描述:
  目前在一个很大的平面房间里有 n 个无线路由器,每个无线路由器都固定在某个点上。任何两个无线路由器只要距离不超过 r 就能互相建立网络连接。
  除此以外,另有 m 个可以摆放无线路由器的位置。你可以在这些位置中选择至多 k 个增设新的路由器。
  你的目标是使得第 1 个路由器和第 2 个路由器之间的网络连接经过尽量少的中转路由器。请问在最优方案下中转路由器的最少个数是多少?
输入格式
  第一行包含四个正整数 n,m,k,r。(2 ≤ n ≤ 100,1 ≤ k ≤ m ≤ 100, 1 ≤ r ≤ 108)。
  接下来 n 行,每行包含两个整数 xi 和 yi,表示一个已经放置好的无线 路由器在 (xi, yi) 点处。输入数据保证第 1 和第 2 个路由器在仅有这 n 个路由器的情况下已经可以互相连接(经过一系列的中转路由器)。
  接下来 m 行,每行包含两个整数 xi 和 yi,表示 (xi, yi) 点处可以增设 一个路由器。
  输入中所有的坐标的绝对值不超过 108,保证输入中的坐标各不相同。
输出格式
  输出只有一个数,即在指定的位置中增设 k 个路由器后,从第 1 个路 由器到第 2 个路由器最少经过的中转路由器的个数。
样例输入
5 3 1 3
0 0
5 5
0 3
0 5
3 5
3 3
4 4
3 0
样例输出
2
该题主要是利用bfs,内嵌一个数组,用来储存包含在m个点中的中转路由器的个数,判断每一个路由器此前经历过的包含在m个点中的中转路由器的个数是否<=k
代码如下:

n,m,k,r = map(int, input().split())
listnm = [] # 用于储存n+m个点的坐标信息
listm = [] # 用于储存m个点的坐标信息,后面将输入数据变成str是为了便于储存在字典中,因为列表是不能作为字典的key
dict_coordinate = {}
for i in range(n):
    list1 = [int(x) for x in input().split()]
    listnm.append('+'+str(list1[0]) + '+' +str(list1[1]))
for i in range(m):
    list1 = [int(x) for x in input().split()]
    listm.append('+'+str(list1[0]) + '+' +str(list1[1]))
    listnm.append('+'+str(list1[0]) + '+' +str(list1[1]))

def radius2(a,b): # 计算两坐标的r**2
    c = a.index('+',1)
    d = b.index('+',1)
    return (eval(a[:c]) - eval(b[:d]))**2 + (eval(a[c:]) - eval(b[d:]))**2

def less_r_n(coordinate,r): # 找到距离<r**2的点,并储存在字典中,便于查找
    global dict_coordinate
    for i in listnm:
        if i != coordinate and radius2(coordinate,i) <= r**2:
            if coordinate not in dict_coordinate.keys():
                dict_coordinate[coordinate] = [i]
            else:
                dict_coordinate[coordinate].append(i)

def if_in_listm(i): # 判断点是否属于m个坐标中
    if i in listm:
        return 1
    else:
        return 0

for i in range(n+m):
    less_r_n(listnm[i],r)

def bfs(local1,local2,k): # BFS遍历算法
    transfer_number = [101 for i in range(n + m)]
    through_k = [0 for i in range(n + m)]
    transfer_number[listnm.index(local1)] = 0
    seen = set()
    seen.add(local1)
    queue = []
    queue.append(local1)
    while (len(queue) > 0):
        coordinate = queue.pop(0)
        list1 = dict_coordinate[coordinate]
        for value in list1:
            if value not in seen:
                loction = listnm.index(value)
                loction1 = listnm.index(coordinate)
                if through_k[loction1] + if_in_listm(value) <= k:
                    through_k[loction] = through_k[loction1] + if_in_listm(value)
                    if 1 + transfer_number[loction1] < transfer_number[loction]:
                        transfer_number[loction] = 1 + transfer_number[loction1]
                        queue.append(value)
                        seen.add(value)
                    if 1 + transfer_number[loction1] == transfer_number[loction]:
                        through_k[loction] -= if_in_listm(value) 
                        queue.append(value)
                        seen.add(value)
    return(transfer_number[listnm.index(local2)]-1)

ans = bfs(listnm[0],listnm[1],k)
print(ans)

猜你喜欢

转载自blog.csdn.net/weixin_42149855/article/details/82414079