• 【第二届全国高校绿色计算大赛 预赛第二阶段(Python)】Tarjan + 最短路


    运输成本

    题意

    给出一个有向图,如果两个城市之间可以互相到达,那么他们就是一个联邦,对于同一个联邦的两个城市,他们之间运输成本为 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
    '''
    
  • 相关阅读:
    MAC配置DNS服务器
    真机IOS8.3以上的文件夹共享
    appium + python的环境配置_windows
    python 的时间与日期
    sublimetext 2 编译文件带input时 提示 EOFError: EOF when reading a line
    cmd无法输入中文解决方案
    配置python学习环境遇到的问题:[Decode error
    monkey初接触
    Android logcat输出中文乱码
    运行 命令框不记录打过的命令,重启后CMD里面是空的.上次打过的命令消失了.
  • 原文地址:https://www.cnblogs.com/valk3/p/13561936.html
Copyright © 2020-2023  润新知