外星人
最近,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)<L(V,W)。
举个例子来说明,所有具有最高Imp的站点都会被别的站点感兴趣。如果V是一个具有最高Imp的站点,由于L(V,V)=0,所以V只对具有最高Imp的站点感兴趣。我们定义B(V)为V感兴趣的站点的集合。
外星人希望计算所有站点的信息量,即所有站点的│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<inheap[heap[i shr 1]].key) do
begin
t:=heap[i];
heap[i]:=heap[i shr 1];
heap[i shr 1]:=t;
inheap[heap[i shr 1]].nr:=i shr 1;
inheap[heap[i]].nr:=i;
i:=i shr 1;
end;
end;
procedure decreasekey(nr,dk:longint);
begin
if dk<inheap[nr].key then
begin
inheap[nr].key:=dk;
up(inheap[nr].nr);
end;
end;
procedure insert(nr,key:longint);
begin
inc(heapn);
heap[heapn]:=nr;
inheap[nr].nr:=heapn;
inheap[nr].key:=key;
up(heapn);
end;
procedure extractmin(var el,key:longint);
var
i,t,l,r,smallest:longint;
begin
el:=heap[1];
key:=inheap[heap[1]].key;
heap[1]:=heap[heapn];
inheap[heap[1]].nr:=1;
dec(heapn);
smallest:=1;
repeat
i:=smallest;
l:=2*i;
r:=2*i+1;
if (l<=heapn) and (inheap[heap[l]].key<inheap[heap[i]].key) then smallest:=l else smallest := i;
if (r<=heapn) and (inheap[heap[r]].key<inheap[heap[smallest]].key) then smallest := r;
if smallest <> 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 r<rank[i] then r:=rank[i];
end;
for i:=1 to m do
begin
readln(a,b,t);
connect(a,b,t);
connect(b,a,t);
end;
end;
procedure computenearest;
var
rr,i,j,key:longint;
begin
for rr:=1 to 9 do
begin
makeemptyheap(n);
for i:=1 to n do if rank[i]>rr 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 key<nearestr[i,ar] then
begin
inc_num(1);
for j:=1 to connn[i] do
begin
if visited[conn[i,j].nr]<>nr 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.
本文介绍了一种计算外星人站点网络中各站点存储数据量的方法。该网络由多个站点组成,每个站点有不同的重要程度。文章详细阐述了算法步骤,包括求最短路径及判断站点间的兴趣关系,并提供了完整的程序实现。
5万+

被折叠的 条评论
为什么被折叠?



