题目大意
给一张无向图,图上每个点都有一个点权,有些点之间有边相连,且每条边有边权,现在给起点和终点,要求找出所有的路径满足从起点到终点的边权和最小,这些路径中点权和最大值
输入
每个输入包含一个测试用例,每个用例的第一行有4个正整数
N
,
M
,
C
1
,
C
2
N, M, C_1, C_2
N,M,C1,C2
N
(
N
≤
500
)
N(N \leq 500)
N(N≤500)是点的数量(从0~
N
−
1
N-1
N−1)
M
M
M是边的数量
C
1
C_1
C1起点
C
2
C_2
C2终点
第二行有
N
N
N个整数,第
i
i
i个数表示第
i
i
i个点的点权
接着有
M
M
M行,每行有三个整数
c
1
,
c
2
,
L
c_1, c_2, L
c1,c2,L,表示
c
1
c
2
c_1c_2
c1c2两个点之间的边权是
L
L
L
输出
对于每个测试样例输出起点和终点之间边值和最小的路径的条数和这些路径中权值和最大的值,并以一行输出
样例输入
5 6 0 2
1 2 1 5 3
0 1 1
0 2 2
0 3 1
1 2 1
2 4 1
3 4 1
样例输出
2 4
解析
这题可以用dijkstra
算法去解,dis[i]
保存起点到i
的最小边权和,value[i]
保存起点到i
的最大点权和,weight[i]
保存每个点的点权,num[i]
表示起点到i
的最短路径的条数,vis[i]
表示i
点是否访问过,edge[i][j]
保存i
和j
之间的边权。
每次出现dis[mark] + edge[mark][j] < dis[j]
时,更新dis
、num
和value
如果出现dis[mark] + edge[mark][j] == dis[j]
时,更新num
,如果同时还有value[mark] + weight[j] > value[j]
,则更新value
INF = 0xffffffff #无穷大
n, m, c1, c2 = map(int, input().split())
weight = list(map(int, input().split()))
value = [INF for i in range(n)]
value[c1] = weight[c1]
dis = [INF for i in range(n)]
dis[c1] = 0 #将起点与起点的距离设为0
num = [0] * n
num[c1] = 1
vis = [False for i in range(n)]
edge = [[INF for i in range(n)] for j in range(n)]
for i in range(m):
a, b, c = map(int, input().split())
edge[a][b] = edge[b][a] = c
for i in range(n):
mark = -1
minn = INF
for j in range(n): #找出当前距离起点最近的点
if vis[j] == False and dis[j] < minn:
mark = j
minn = dis[j]
if mark == -1 or mark == c2: #如果没找到或者找到的点是终点
break
vis[mark] = True #将找到的点标记为已访问
for j in range(n):
if vis[j] == False and edge[mark][j] != INF: #如果点没有访问过并且标记的点和这个点之间有边
if dis[mark] + edge[mark][j] < dis[j]:
dis[j] = dis[mark] + edge[mark][j]
num[j] = num[mark]
value[j] = value[mark] + weight[j]
elif dis[mark] + edge[mark][j] == dis[j]:
num[j] = num[j] + num[mark]
if value[mark] + weight[j] > value[j]:
value[j] = value[mark] + weight[j]
print("%d %d" % (num[c2], value[c2]))