Specific Graph and need to more Creative solution

巧了我就是萌 提交于 2021-02-07 08:55:37

问题


Directed Graph (|V|=a, |E|=b) is given. each vertexes has specific weight. we want for each vertex (1..a) find a vertex with maximum weight that can be reachable from that vertex.

Update 1: one nice answer is prepare by @Paul in O(b + a log a). but I search for O(a + b) algorithms, if any?

Is there any different efficient or fastest any other ways for doing it?


回答1:


Yes, it's possible to modify Tarjan's SCC algorithm to solve this problem in linear time.

Tarjan's algorithm uses two node fields to drive its SCC finding logic: index, which represents the order in which the algorithm discovers the nodes; and lowlink, the minimum index reachable by a sequence of tree arcs followed by a back arc. As part of the same depth-first traversal, we can compute another field, maxweight, which has one of two meanings:

  • For a node not yet included in a finished SCC, it represents the maximum weight reachable by a sequence of tree arcs, optionally followed by a cross arc to another SCC and then any subsequent path.

  • For nodes in a finished SCC, it represents the maximum weight reachable.

The logic for computing maxweight is as follows. If we discover an arc from v to a new node w, then vw is a tree arc, so we compute w.maxweight recursively and update v.maxweight = max(v.maxweight, w.maxweight). If w is on the stack, then we do nothing, because vw is a back arc and not included in the definition of maxweight. Otherwise, vw is a cross arc, and we do the same update that we would have done for a tree arc, just without the recursive call.

When Tarjan's algorithm identifies an SCC, it's because it has a node r with r.lowlink == r.index. Since r is the depth-first search root of this SCC, its value of maxweight is correct for the whole SCC. Instead of recording each node in the SCC, we simply update its maxweight to r.maxweight.




回答2:


Sort all nodes by weight in decreasing order and create the graph g' with all edges in E reversed (i.e. if there's an edge a -> b in g, there's an edge b -> a in g'). In this graph you can now propagate the maximum-value by simple DFS. Do this iteratively for all nodes and terminate when a maximum-weight has already been assigned.

As pseudocode:

dfs_assign_weight_reachable(node, weight):
    if node.max_weight_reachable >= weight:
        return

    node.max_weight_reachable = weight

    for n = neighbor of node:
        dfs_assign_weight_reachable(n, weight)

g' = g with all edges reversed
nodes = nodes from g' sorted descendingly by weight
assign max_weight_reachable = -inf to each node in nodes

for node in nodes:
    dfs_assign_weight_reachable(node, node.weight)

UPDATE:
The tight bound is O(b + a log a). a log a is caused by the sorting step. And each edge gets visited once during the reversal step and once during the assigning maximum weights, giving the second term in the max-expression.

Acknowledgement:
I'd like to thank @SerialLazer for the time invested in a discussion about the time-complexity of the above algorithm and helping me figure out the correct bound.



来源:https://stackoverflow.com/questions/64945501/specific-graph-and-need-to-more-creative-solution

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!