📅  最后修改于: 2023-12-03 14:58:21.086000             🧑  作者: Mango
本问题是关于图论的问题。给定一个无向加权图G = (V, E),其中V是节点的集合,E是边集合,每条边 (u, v) 的权重为 w(u, v)。在该图中,给定源节点s和目标节点t。我们需要找到从s到t的一条简单路径,使得路径上所有边的权重和最大。让该权重和为P。现在添加一些额外的边 (u, v),这将使得图形成一个环。我们需要添加的边 (u, v) 的权重为X。此时,找到从s到t的一条简单路径,使得路径上所有边的权重和最大,并返回路径的权重和。
输入的第一行包含两个整数 n 和 m ,分别表示节点数和边数。
接下来的m行包含三个整数u, v和w,表示无向加权边 (u, v) 的两个节点和它们之间的权重w。
接下来一行包含两个整数s和t,表示需要找到的源节点和目标节点。
接下来一行包含一个整数 q ,表示需要添加的边数。
接下来q行,每行包含三个整数u, v和X,表示需要添加一条从u到v的边,其权重为X。
图保证无重边和自环,而且原始图保证从s到t至少存在一条路径。
输出一个整数,表示找到从s到t的一条简单路径,使得路径上所有边的权重和最大,并返回路径的权重和。
输入:
3 3
1 2 3
2 3 4
3 1 5
1 2
1
输出:
9
本题是一道图论的问题。通过给定的源节点和目的节点,需要找到连接这两个节点的一条最大权重的路径。当一个节点连通到自己或者存在环时,我们可以想到利用Floyd华沙尔算法求解最短(长)路径。最长路径长度是所有最短路径长度取负得到的。但是,本题新增了一些边,这些新增的边会形成一个环,我们需要对此进行分析。
我们先在原图中找出从s到t的最长路径P。如果新添加的边没有连接P上的任何节点,那么它不会对答案造成任何影响。否则,它将形成一个环,我们需要找到路径P上的边(L, R),连接它们的这个边(u, v),并将其权重设置为X。然后,我们可以通过将P分解为从s到L的路径1,从L到R的路径2,和从R到t的路径3。设路径2包含k个节点,那么从源节点到目标节点的最长路径的长度是max(P,P1 + X + k*P2 + X + P3)。
我们需要预处理出P1,P2和P3。接下来只要遍历所有新添加的边(u, v),计算以上式子的值即可。
def get_longest_path(n, m, edges, s, t):
# 初始图和图的反向的权重
graph = [[] for i in range(n)]
graph_r = [[] for i in range(n)]
for u, v, w in edges:
graph[u - 1].append((v - 1, w))
graph_r[v - 1].append((u - 1, w))
# 分别计算从 s 到 t 和从 t 到 s 的最长路径
dist_s = [float('-infinity')] * n
pq_s = [(0, s - 1)]
dist_s[s - 1] = 0
while pq_s:
dist, u = heapq.heappop(pq_s)
if dist_s[u] != dist:
continue
for v, w in graph[u]:
if dist_s[v] < dist + w:
dist_s[v] = dist + w
heapq.heappush(pq_s, (dist_s[v], v))
dist_t = [float('-infinity')] * n
pq_t = [(0, t - 1)]
dist_t[t - 1] = 0
while pq_t:
dist, u = heapq.heappop(pq_t)
if dist_t[u] != dist:
continue
for v, w in graph_r[u]:
if dist_t[v] < dist + w:
dist_t[v] = dist + w
heapq.heappush(pq_t, (dist_t[v], v))
# 计算从 s 到 t 最长路径上的所有边的权重和
ans = dist_s[t - 1]
for u, v, w in edges:
ans = max(ans, dist_s[u - 1] + w + dist_t[v - 1])
return ans
def solve(n, m, edges, s, t, q, new_edges):
# 计算原图中从 s 到 t 的最长路径
P = get_longest_path(n, m, edges, s, t)
# 计算从 s 到 t 最长路径上的所有边的权重和
P1, P2, P3 = 0, 0, 0
L, R = None, None
for i in range(len(new_edges)):
u, v, w = new_edges[i]
if P1 == 0 and (u == s or v == s):
P1 = get_longest_path(n, m, edges, s, u if v == s else v)
if P3 == 0 and (u == t or v == t):
P3 = get_longest_path(n, m, edges, u if v == t else v, t)
if u == s and v == t:
ans = max(P, P1 + w + P3)
return ans
elif u == s or u == t:
x, y = u, v
elif v == s or v == t:
x, y = v, u
else:
continue
if P2 < get_longest_path(n, m, edges, x, y):
P2 = get_longest_path(n, m, edges, x, y)
L, R = x, y
# 组合计算 s 到 t 的最长路径
ans = P
if L is not None and R is not None:
ans = max(ans, P1 + new_edges[-1][2] + P2 + new_edges[-1][2] + P3)
return ans
n, m = 3, 3
edges = [(1, 2, 3), (2, 3, 4), (3, 1, 5)]
s, t = 1, 2
q = 1
new_edges = [(3, 2, 1)]
ans = solve(n, m, edges, s, t, q, new_edges)
print(ans)
注:以上是python实现的参考代码,需要用到堆(heapq)的数据结构辅助计算,可以自行百度了解。