P3844服务器信息储存
问题描述
Byteland王国准备在各服务器间建立大型网络并提供多种服务。
网络由n台服务器组成,用双向的线连接。两台服务器之间最多只能有一条线直接连接,同时,每台服务器最多只能和10台服务器直接连接,但是任意两台服务器间必然存在一条路径将它们连接在一起。每条传输线都有一个固定传输的速度。δ(V, W)表示服务器V和W之间的最短路径长度,且对任意的V有δ(V, V)=0。
有些服务器比别的服务器提供更多的服务,它们的重要程度要高一些。我们用r(V)表示服务器V的重要程度(rank)。rank越高的服务器越重要。
每台服务器都会存储它附近的服务器的信息。当然,不是所有服务器的信息都存,只有感兴趣的服务器信息才会被存储。服务器V对服务器W感兴趣是指,不存在服务器U满足,r(U)>r(W)且δ(V, U)<=δ(V, W)。
举个例子来说,所有具有最高rank的服务器都会被别的服务器感兴趣。如果V是一台具有最高rank的服务器,由于δ(V, V)=0,所以V只对具有最高rank的服务器感兴趣。我们定义B(V)为V感兴趣的服务器的集合。
我们希望计算所有服务器储存的信息量,即所有服务器的|B(V)|之和。Byteland王国并不希望存储大量的数据,所以所有服务器存储的数据量(|B(V)|之和)不会超过30n。
你的任务是写一个程序,读入Byteland王国的网络分布,计算所有服务器存储的数据量。
输入格式
第一行两个整数n和m,(1≤n≤30000,1≤m≤5n)。n表示服务器的数量,m表示传输线的数量。
接下来n行,每行一个整数,第i行的整数为r(i)(1≤r(i)≤10),表示第i台服务器的rank。
接下来m行,每行表示各条传输线的信息,包含三个整数a,b,t(1≤t≤1000,1≤a,b≤n,a≠b)。a和b是传榆线所连接的两台服务器的编号,t是传输线的长度。
输出格式
一个整数,表示所有服务器存储的数据总量,即|B(V)|之和。
样例输入
4 3
2
3
1
1
1 4 30
2 3 20
3 4 20
样例输出
9
提示
样例解释
B(1)={1,2},B(2)={2},B(3)={2,3},B(4)={1,2,3,4}。
数据范围
对于 30%的数据,n≤100,m<=300。
对于 60%的数据,n≤1000,m<=20000。
对于 100%的数据, 1≤n≤30000,1≤m≤5n
首先预处理出$dis[i][k]$表示$i$号点所有到$rank=k$的点的距离的最小值。实现方式是在dijkstra时向堆中添加所有$rank=k$的点作为起点。
然后处理出$mindis[i][k]$表示$i$号点到所有$rank>=k$的点的距离的最小值。
最后枚举点$i$,跑一次dijkstra,算出有那些点对$i$号点感兴趣,如果一个点$x$出堆时,它和$i$的距离小于$mindis[x][rank[i]]$那么说明不存在rank大于$i$的点和$x$的距离小于等于$dis(x,i)$,因此$x$对$i$感兴趣。反之如果$dis(x,i)$大于等于$mindis[x][rank[i]]$,那么从$x$点再拓展出的点一定不可能对$i$感兴趣。因为假设从$x$经过一条长度为$k$的边到达$y$,那么$dis(y,i)=dis(x,i)+k$,而$$mindis[y][rank[i]]<=mindis[x][rank[i]]+k<=dis(x,i)+k=dis(y,i)$$
所以我们可以不从$x$点拓展新的节点,即$continue$
代码:
1 |
|