SSL P2133 腾讯大战360

206 篇文章 0 订阅
27 篇文章 0 订阅

题目大意:
有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.
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值