1. 程式人生 > >CCF-201609-4-交通規劃

CCF-201609-4-交通規劃

這題照樣套模板,但是有個地方要修改。

題目意思是:求最短路徑的同時還要保證這些路徑的總權值最小
在兩條總權值相等的路徑中,經過結點最多的那個最好。你想想,如果我能從原來已有的結點上再加一條到達目標。是不是好過從上一個結點再拉一條呢。兩條總權值相等,結點數相等的路徑,最後一條邊權值越小的越好。

總的來說,在更新最短路徑的時候,只比對最後一條邊即可(無論結點數誰多誰少,只看最後那條邊就可以),如果最後一條邊比原來的路徑的最後一條邊小,就更新。

程式碼只要在原來的dijkstra演算法上改一下就好了。
直接把“edge[1] + minCost < costs[edge[0]]”的小於號改為小於等於號“edge[1] + minCost <= costs[edge[0]]”。

我這裡新加一個儲存到父結點的邊權值,在每次更新最短路徑的時候,看新的父結點的邊值是否小於以前的,是就更改父結點和父結點邊的權值。修改起來有點麻煩,但是這樣利於後面的算總權值和(總費用)。

這題n最大10000。。。這裡演算法時間複雜度為O(n^2),嗯。。。所以最後只過了80%的用例,80分。後面20%用例執行超時。

python程式碼:

def dij(start, graph):
    n = len(graph)
    costs = [99999 for _ in range(n)]
    parents = [-1 for _ in range(n)]
    parents_costs = [99999 for _ in range(n)]
    costs[start] = 0
    visited = [False for _ in range(n)]
    t = []
    while len(t) < n:
        # 每次從costs裡找最短花銷,把最短花銷的結點加進t中
        minCost = 99999
        minNode = start
        for i in range(len(costs)):
            if not visited[i] and costs[i] < minCost:
                minNode = i
                minCost = costs[i]
        t.append(minNode)
        visited[minNode] = True

        # 找這點的鄰邊(子結點不在t裡面)
        # 如果鄰邊的子結點的路徑花銷小於原來的花銷,就更新花銷和父結點
        for edge in graph[minNode]:
            if not visited[edge[0]] and edge[1] + minCost <= costs[edge[0]]:
                if edge[1] + minCost < costs[edge[0]]:
                    costs[edge[0]] = edge[1] + minCost
                    parents[edge[0]] = minNode
                    parents_costs[edge[0]] = edge[1]
                elif edge[1] < parents_costs[edge[0]]:
                    parents[edge[0]] = minNode
                    parents_costs[edge[0]] = edge[1]
    return costs, parents, parents_costs


n, m = map(int, input().split())
# 鄰接表
graph = [[] for _ in range(n)]
for i in range(m):
    edge = list(map(int, input().split()))
    graph[edge[0] - 1].append([edge[1] - 1, edge[2]])
    graph[edge[1] - 1].append([edge[0] - 1, edge[2]])

costs, parents, parents_costs = dij(0, graph)

# 算總費用
total = 0
for i in range(1, len(parents_costs)):
    total += parents_costs[i]
print(total)