外星人
最近,RCDH研究外星人的交流方式很特别。它们会设置一个交流网。网络由n个站点组成,用双向的线连接。两个站点之间最多只能有一条线直接连接,同时每个站点最多只能和10个站点直接连接,但是任意两个站点之间必须存在一条路径将它们连接一起。每条传输线都有一个固定的传输速度。L(V,W)表示站点V和W之间的最短路径长度,且对任意的V有L(V,V)=0。
外星人对每个站点的偏爱程度不同,所以有些站点的重要度会高一些。我们用R(V)表示站点V的重要程度(Imp)。Imp越高站点越重要。
每个站点都会存储周围站点的信息,以防丢失。当然站点的空间有限,不会存储所有的站点信息,只有通过它们自己的人工智能判断后感觉有兴趣的才会存储。站点V对站点W感兴趣是指,不存在站点U满足:R(U)>R(W)且L(V,U)
外星人希望计算所有站点的信息量,即所有站点的│B(V)│之和。火星人并不希望存储太多的数据,所以所有站点存储的数据量(│B(V)│之和)不会超过30n。
你的任务是写一个程序,读入外星人的站点网络分布,计算所有站点存储的数据量。
输入:
第一行两个整数n和m。n表示站点的数量,m表示传输线的数量。
接下来n行,每行有一个整数,第I行的整数为R(I),表示第I个站点的Imp。
接下来m行,每行表示各传输线的信息,包含3个整数a,b,t,a和b是传输线所连接的两个站点的编号,t是传输线的长度。
输出:
一个整数,表示所有站点存储的数据总量,即│B(V)│之和。
【样例】
输入 6 5
4
2
3
2
2
4
1 2 1
2 3 1
3 4 1
4 5 1
5 6 1
输出 17
【数据规模】
对于100%的数据
1<=n<=30000
1<=m<=5n
1<=R(i)<=10
1<=t<=1000
1<=a,b<=n
a≠b
算法:图论
(1) 分别以Imp=1,2,3……,10的节点集合作为起点,求该节点(集合)到所有地点的最短距离(其实也就是所有点到该节点(集合)的最短路径);
(2) 以每个点为起点,求该点到所有点的最短距离。当求得某节点的最短距离的同时,根据求得的最短路径和该节点到Imp大于起点的节点(集合)的最短距离,判断该点是否对起点感兴趣。如果感兴趣,则找到一对感兴趣的点对;否则,停止扩展该节点,因为该节点不可能扩展出对起点感兴趣的点。
program et;
const
maxn=100000;
maxd=1000*maxn+1;
maxsummul=30;
type
inheapt=record
nr,key:longint;
end;
connt=record
nr,t:longint;
end;
var
inheap:array [0..maxn] of inheapt;
rank,heap,visited,connn:array [0..maxn] of longint;
heapn:longint;
conn:array [0..maxn,0..10] of connt;
nearestr:array [0..maxn,0..10] of longint;
n,m,r,num:longint;
procedure makeemptyheap(n:longint);
var
i:longint;
begin
for i:=1 to n do
begin
heap[i]:=i;
inheap[i].nr:=i;
inheap[i].key:=maxd;
end;
heapn:=n;
end;
procedure up(i:longint);
var
t:longint;
begin
while (i<>1) and (inheap[heap[i]].key i then
begin
t:=heap[i];
heap[i]:=heap[smallest];
heap[smallest]:=t;
inheap[heap[i]].nr:=i;
inheap[heap[smallest]].nr := smallest;
end;
until smallest=i;
end;
procedure inc_num(a:longint);
begin
inc(num,a);
if (num>maxsummul*n) then
begin
writeln('Total sum too big: ',num);
halt(1);
end
end;
procedure connect(a,b,t:longint);
begin
inc(connn[a]);
conn[a,connn[a]].nr:=b;
conn[a,connn[a]].t:=t;
end;
procedure init;
var
i,a,b,t:longint;
begin
num:=0;
readln(n,m);
for i:=1 to n do
begin
readln(rank[i]);
if rrr then decreasekey(i,0);
while heapn>0 do
begin
extractmin(i,key);
nearestr[i,rr]:=key;
for j:=1 to connn[i] do decreasekey(conn[i,j].nr,key+conn[i,j].t);
end;
end;
end;
procedure reaches(nr:longint);
var
i,j,key,ar:longint;
begin
heapn:=0;
ar:=rank[nr];
if ar=r then inc_num(n)
else
begin
insert(nr,0);
visited[nr]:=nr;
while (heapn>0) do
begin
extractmin(i,key);
if keynr then
begin
insert(conn[i,j].nr,key+conn[i,j].t);
visited[conn[i,j].nr]:=nr;
end
else decreasekey(conn[i,j].nr,key+conn[i,j].t);
end;
end;
end
end;
end;
procedure main;
var
i:longint;
begin
for i:=1 to n do reaches(i);
end;
begin
assign(input,'et.in'); reset(input);
assign(output,'et.out'); rewrite(output);
init;
computenearest;
main;
writeln(num);
close(input); close(output);
end.