1. 程式人生 > >CCF-201409-4-最優配餐

CCF-201409-4-最優配餐

這題真的拓展了我對BFS的認識,bfs還可以多個源點同時開始bfs,以前一直都是一個源點開始bfs,這題因為有多家店,找最短路徑,就必須要一起來bfs,把起點都放進佇列中,然後開始bfs。如果分開一間間店bfs的話,最後還要比較那家店最短。時間複雜度會爆炸。
ccf裡面同樣的思路,只有c++的程式碼才能100,java和python程式碼都超時,分別只有80和70分。我同學的java程式碼以前還能拿90,現在提交上去只有80,java和c++的程式碼不是我寫的就不放出來了。
python程式碼(70)

from queue import Queue

# 返回成本
def bfs(rests, matrix, vis, k):
    cnt = 0
    dires = [[0, 1], [0, -1], [1, 0], [-1, 0]]
    queue = Queue()  # queue裡面的元素為[x, y, step]形式,step為步數
    for rest in rests:
        queue.put(rest + [1])
    total = 0
    while not queue.empty():
        x, y, step = queue.get()
        for dx, dy in dires:
            nx, ny = x + dx, y + dy
            if 0 <= nx < len(matrix) and \
                    0 <= ny < len(matrix) and \
                    matrix[nx][ny] != -1 and \
                    not vis[nx][ny]:
                if matrix[nx][ny] > 0:
                    total += matrix[nx][ny] * step
                    cnt += 1
                if cnt == k:
                    return total
                queue.put([nx, ny, step + 1])
                vis[nx][ny] = True


n, m, k, d = map(int, input().split())
matrix = [[0] * n for _ in range(n)]
rests = []  # 店
vis = [[False] * n for _ in range(n)]

for i in range(m):
    x, y = map(int, input().split())
    matrix[x - 1][y - 1] = -1
    rests.append([x - 1, y - 1])
    vis[x - 1][y - 1] = True

for i in range(k):
    x, y, cost = map(int, input().split())
    # 在矩陣中的顧客位置用訂餐量標記,
    # 這裡加等是因為相同的位置有多位顧客,所以在原來的位置上加等訂餐量
    matrix[x - 1][y - 1] += cost

for i in range(d):
    x, y = map(int, input().split())
    matrix[x - 1][y - 1] = -1  # -1代表障礙
    vis[x - 1][y - 1] = True

# 從所有店開始同時出發廣搜
print(bfs(rests, matrix, vis, k))

# 10 2 3 3
# 1 1
# 8 8
# 1 5 1
# 2 3 3
# 6 7 2
# 1 2
# 2 2
# 6 8

# 1000 1 1 3
# 1 1
# 999 999 1
# 1 2
# 2 2
# 6 8