8.12 腾讯大战360 2133

题目

2010年11月3日,是一个难忘的日子。 腾讯发布消息:存360则,不留QQ。留QQ,则须卸360。 360则表示360与QQ可以共存。 这也就标志着腾讯与360的大战就此开始!
现在,腾讯与360由于身处异地,非常迫切地想在最短的时间内相遇,然后干一架。但是由于双方的技术员都在努力地编程序想干掉对方,所以他们希望你来帮他们找到一个最好的方案使得相遇的时间最短。
在此我们定义“相遇”为:两个人皆在同一个有编号的城市上就可以了,并且这两个人均可以站在原地等另外一个人。也就是说,在这里我们不考虑两人在路中间相遇。

[数据范围]每组都是n=5000 m=5000 并且保证运算过程中的所有值都不会超过117901063

输出只有一行,D,表示二者“相遇”的最短时间。当然,如果无法相遇则输出“Peace!”

题解

一道很水很水的,SPFA
嗯,真的很水
至于为什么早上没过,纯属傻了————
明明只用做一遍的东西,为什么做了n遍?是嫌时间太多么?(并没有,是忘记了只用做一遍)
QAQ,我的分啊!Orz。。。。。

现在才是题解
因为需要让两人相遇在一个点上,所以可以做一遍从腾讯所在城市的SPFA,然后做一遍从360开始的SPFA,接着枚举n个点,找最小的max(d[i],dz[i]),即为答案
因为是两个人,所以时间应取两人到达当前点最短路中的最大值

时间复杂度O(n+m)

代码

type
  arr=array[0..100000]of longint;
var
  n,m,i,j,k,s,t,ans:longint;
  x,y,w,v,ls,ne,d,dz:arr;
  b:array[0..10000]of boolean;

function max(a,b:longint):longint;
begin
  if a>b then exit(a) else exit(b);
end;

procedure spfa(var d:arr;s:longint);
var
  i,j,k,h,tail:longint;
begin
  fillchar(b,sizeof(b),true);
  h:=0;tail:=1;v[1]:=s;d[s]:=0;b[s]:=false;
  while h<tail do
    begin
      inc(h);
      k:=ls[v[h]];
      while k>0 do
        begin
          if d[v[h]]+w[k]<d[y[k]] then
            begin
              d[y[k]]:=d[v[h]]+w[k];
              if b[y[k]] then
                begin
                  inc(tail);
                  b[y[k]]:=false;
                  v[tail]:=y[k];
                end;
            end;
          k:=ne[k];
        end;
      b[v[h]]:=true;
    end;
end;

begin
  readln(n,m);
  for i:=1 to m do
    begin
      inc(j);
      readln(x[j],y[j],w[j]);
      ne[j]:=ls[x[j]];ls[x[j]]:=j;
      inc(j);
      x[j]:=y[j-1];y[j]:=x[j-1];w[j]:=w[j-1];
      ne[j]:=ls[x[j]];ls[x[j]]:=j;
    end;
  ans:=maxlongint;
  readln(s,t);
  fillchar(d,sizeof(d),$7f);
  spfa(d,s);
  fillchar(dz,sizeof(dz),$7f);
  spfa(dz,t);
  for i:=1 to n do
    begin
      j:=max(d[i],dz[i]);
      if j<ans then ans:=j;
    end;
  if ans<>d[0] then writeln(ans) else writeln('Peace!');
end.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值