Description
外星人入侵地球。可怕的吃人外星人正在全国各地依次序建立它们的基地。
全国共有N(1≤ N ≤10,000)座城市,城市编号1~N。城市之间有M(0≤ M ≤100,000)条双向道路相连。外星人计划建立A(0≤A≤N)个基地。
你只有在距离当前所有外星人基地至少K(1≤K≤100)单位长度的城市才能得到安全。
所以你必须赶快写一个程序决定走到哪里去。
Input
第1行:4个整数N, M, A, K
接下来M行,每行3个整数T1, T2(1≤T1 < <script type="math/tex" id="MathJax-Element-3"><</script>T2≤N)和D(1≤D≤100),表示城市T1与T2之间有一条长度为D的道路。两个城市之间最多有一条直连道路。
接下来A行,每行1个整数Bi(1≤Bi≤N),表示外星人依次序建的第i个基地所在的城市编号。
Output
共A行,第i行1个整数,表示当外星人建好第i个基地后,距离当前所有基地B1,B2,…,Bi至少K长度的城市的数量。
Sample Input
7 6 3 3
1 2 1
1 3 1
2 5 1
3 6 1
1 4 1
4 7 2
2
1
4
Sample Output
2
1
0
分析:
我们一开始以第一个基地为起点先跑一遍SPFA。然后对于每个基地,我们都进行BFS。然后会超时。我们开k比较小,就可以优化一下。我们用d[i]表示从基地跑到i点后,还能跑多远。然后当我们从x到y时,w为这两点的距离,如果d[x]+w<=d[y]或者
d[x]+w<=0时,我们就无需再找了。
代码:
const
MaxE=10001;
MaxV=210001;
maxn=50001;
type
rec=record
x,y,w,next:longint;
end;
var
n,m,c,q,i,x,y,t,s,p,ans,w:longint;
g:array [1..Maxv] of rec;
ls:array [1..Maxe] of longint;
b:array [1..maxe] of boolean;
v,d,list:array [1..maxe] of longint;
procedure spfa;
var
head,tail,t,i:longint;
begin
head:=0; tail:=1;
list[1]:=c;
for i:=1 to n do
d[i]:=maxlongint;
d[c]:=0;
v[c]:=1;
while head<>tail do
begin
head:=head mod maxe+1;
t:=ls[list[head]];
while t>0 do
with g[t] do
begin
if d[x]+w<d[y] then
begin
d[y]:=d[x]+w;
if v[y]=0 then
begin
v[y]:=1;
tail:=tail mod maxe+1;
list[tail]:=y;
end;
end;
t:=next;
end;
v[list[head]]:=0;
end;
ans:=0;
for i:=1 to n do
begin
if q-d[i]<=0 then begin b[i]:=true; inc(ans); end
else b[i]:=false;
d[i]:=q-d[i];
end;
writeln(ans);
end;
procedure bfs(xx:longint);
var l:array [0..maxn+1] of longint;
head,tail,t:longint;
begin
head:=0; tail:=1;
l[1]:=xx;
d[xx]:=q;
if b[xx] then begin ans:=ans-1; b[xx]:=false; end;
repeat
head:=head mod maxn+1;
t:=ls[l[head]];
while t>0 do
begin
with g[t] do
begin
if (d[x]-w>d[y]) and (d[x]-w>0) then
begin
d[y]:=d[x]-w;
if b[y] then begin ans:=ans-1; b[y]:=false; end;
tail:=tail mod maxn+1;
l[tail]:=y;
end;
t:=next;
end;
end;
until head=tail;
writeln(ans);
end;
begin
readln(n,m,p,q);
for i:=1 to m do
begin
readln(x,y,w);
g[i*2-1].x:=x;
g[i*2-1].y:=y;
g[i*2-1].w:=w;
g[i*2-1].next:=ls[x];
ls[x]:=i*2-1;
g[i*2].y:=x;
g[i*2].x:=y;
g[i*2].w:=w;
g[i*2].next:=ls[y];
ls[y]:=i*2;
end;
if p>0 then
begin
readln(c);
spfa;
for i:=2 to p do
begin
readln(c);
bfs(c);
end;
end;
end.