【第二屆全國高校綠色計算大賽 預賽第二階段(Python)】Tarjan + 最短路
阿新 • • 發佈:2020-08-25
運輸成本
題意
給出一個有向圖,如果兩個城市之間可以互相到達,那麼他們就是一個聯邦,對於同一個聯邦的兩個城市,他們之間運輸成本為 0 ,現在讓求出整個圖中的最長路。
思路
首先跑 Tarjan 縮點,然後建立一個超級源點,他到所有點的距離為 0,然後跑最長路。
Python 版的 Dijkstra + 優先佇列
程式碼
''' Autor: valk Date: 2020-08-19 18:23:25 LastEditTime: 2020-08-19 22:07:06 Description: 如果邪惡 是華麗殘酷的樂章 它的終場 我會親手寫上 晨曦的光 風乾最後一行憂傷 黑色的墨 染上安詳 ''' import heapq class Edge: u, v, w = None, None, None def __init__(self, u, v, w): self.u = u self.v = v self.w = w class Solver: def solve(self, n, edges): N = 200010 inf = 10 ** 9 edge = [[] for i in range(N)] edge2 = [[] for i in range(N)] cnt = 0 top = 0 num = 0 dfn = [0 for i in range(N)] low = [0 for i in range(N)] Stack = [0 for i in range(N)] vis = [0 for i in range(N)] fa = [0 for i in range(N)] dis = [0 for i in range(N)] def tarjan(u): nonlocal cnt,dfn,low,vis,num,top,fa,edge,Stack cnt+=1 dfn[u] = low[u] = cnt top+=1 Stack[top] = u vis[u] = 1 for pair in edge[u]: v = pair[0] if dfn[v] == 0: tarjan(v) if low[v] < low[u]: low[u] = low[v] elif (vis[v]): if low[u] > dfn[v]: low[u] = dfn[v] if low[u] == dfn[u]: v = 0 num += 1 v = Stack[top] top -= 1 vis[v] = 0 fa[v] = num while (u != v): v = Stack[top] top -= 1 vis[v] = 0 fa[v] = num def dijkstra(u, n): nonlocal vis, dis, edge2 for i in range(1, n+1): vis[i] = 0 dis[i] = inf dis[u] = 0 q = [] heapq.heappush(q, (dis[u], u)) while (len(q) > 0): pair = heapq.heappop(q) now = pair[1] for node in edge2[now]: to = node[0] w = node[1] if dis[to] > dis[now] + w: dis[to] = dis[now] + w heapq.heappush(q, (dis[to], to)) for i in edges:#print edge[i.u].append((i.v, i.w)) for i in range(1, n + 1): if (dfn[i] == 0): tarjan(i) for i in range(1, n + 1): u=fa[i] for node in edge[i]: if u == fa[node[0]]: continue edge2[u].append((fa[node[0]], -node[1])) for i in range(1, num + 1): edge2[num + 1].append((i, 0)) dijkstra(num + 1, num + 1) ans = inf for i in range(1, num + 2): if dis[i] < ans: ans = dis[i] return -ans ''' 5 1 2 1 2 3 1 3 4 1 4 2 1 4 5 1 0 0 0 '''