题目大意:
有N个点,腾讯与360分别在点S,点T,给出M个a,b,c,表示点a到点b有一条连边(双向边),耗时为c,他们想在最短的时间内相遇,然后干一架。,求二者“相遇”的最短时间,当然,如果无法相遇则输出“Peace!”
在此我们定义“相遇”为:两个人皆在同一个有编号的城市上就可以了,并且这两个人均可以站在原地等另外一个人。也就是说,在这里我们不考虑两人在路中间相遇。
每组数据n=5000 m=5000
并且保证运算过程中的所有值都不会超过117901063
题解:
spfa+邻接表:
我们用点S(腾讯)到N个点的最短路跑一遍,
结果是dis[1,i]
然后点T(360)同上操作,结果是dis[2,i]
然后在max(dis[1,i],dis[2,i])找个最小值。
因为如果腾讯到点i最少要花费dis[1,i]时间,然后360到点i要话费dis[2,i]时间,这时
如果dis[1,i] < dis[2,i] 那么因为题意是允许在原地等待的,那么360和腾许在第i个点相遇的最短时间,则是dis[2,i],同理,dis[2,i] < dis[1,i]则选择dis[1,i],等于就直接搞搞即可。
然后有N个点,每次都这么做,然后找最小值。
因此我们就得到答案:
min(max(dis[1,i],dis[2,i]))
然后注意不能相遇要输出Peace!
时间复杂度:O(3N+2M)
var
list,s,t,w,next:array [0..10001] of longint;
q:array [0..100001,1..2] of longint;
dis:array [1..2,0..5001] of longint;
v:array [1..2,0..5001] of boolean;
x,y,z,xx,yy,i,j,n,m,d,ans:longint;
procedure add(k,aa,bb,cc:longint);
begin
s[k]:=aa;
t[k]:=bb;
w[k]:=cc;
next[k]:=list[s[k]];
list[s[k]]:=k;
end;
procedure spfa;
var
head,tail,i:longint;
begin
head:=0;
tail:=1;
for i:=0 to n do
begin
dis[1,i]:=maxlongint;
dis[2,i]:=maxlongint;
end;
head:=0;
tail:=2;
dis[1,x]:=0;
dis[2,y]:=0;
v[1,x]:=true;
v[2,y]:=true;
q[1,1]:=x; q[1,2]:=1;
q[2,1]:=y; q[2,2]:=2;
while head<tail do
begin
inc(head);
i:=list[q[head,1]];
while i>0 do
begin
if dis[q[head,2],s[i]]+w[i]<dis[q[head,2],t[i]]
then begin
dis[q[head,2],t[i]]:=dis[q[head,2],s[i]]+w[i];
if v[q[head,2],t[i]]=false
then begin
v[q[head,2],t[i]]:=true;
inc(tail);
q[tail,1]:=t[i];
q[tail,2]:=q[head,2];
end;
end;
i:=next[i];
end;
v[q[head,2],q[head,1]]:=false;
end;
end;
function min(aa,bb:longint):longint;
begin
if aa>bb then exit(bb);
exit(aa);
end;
function max(aa,bb:longint):longint;
begin
if aa>bb then exit(aa);
exit(bb);
end;
begin
readln(n,m);
for i:=1 to m do
begin
readln(x,y,z);
inc(d);
add(d,x,y,z);
inc(d);
add(d,y,x,z);
end;
ans:=maxlongint;
readln(x,y);
spfa;
for i:=1 to n do
if dis[1,i]<>maxlongint then
if dis[2,i]<>maxlongint then
ans:=min(ans,max(dis[1,i],dis[2,i]));
if ans=maxlongint
then writeln('Peace!')
else writeln(ans);
end.