POJ3259 Wormholes

题目描述

在一个农场中一共有n个区域,有些区域之间存在双向通道,也会存在一些单向的虫洞,经过通道需要花费时间,穿过虫洞可以减少时间,你的目标是从起点出发再回到起点是能否遇到未来的自己。

样例输入

2
3 3 1
1 2 2
1 3 4
2 3 1
3 1 3
3 2 1
1 2 3
2 3 4
3 1 8

样例输出

No
Yes

思路

O(NVE)
Bellman-ford,判断每个农场是否存在负权环,如果有,就能遇到未来的自己。
const
  maxn=5000;
  maxe=10000000;
type
  edge=record
  a,b,w:longint;
end;
var
  edges:array[1..maxe]of edge;
  dis:array[1..maxn]of longint;
  pre:array[1..maxn]of longint;
  e,n,s,t:longint;
procedure init;
var
  x,y,z,i,j:longint;
begin
  readln(n,s,t);
  for i:=1 to s do
    begin
      readln(x,y,z);
      with edges[i*2-1] do
        begin a:=x;b:=y;w:=z;end;
      with edges[i*2] do
        begin a:=y;b:=x;w:=z;end;
    end;
  e:=s*2;
  for i:=1 to t do
    begin
      readln(x,y,z);
      with edges[i+e] do
        begin a:=x;b:=y;w:=-z;end;
    end;
  e:=e+t;
  fillchar(dis,sizeof(dis),$7f div 3);
  dis[s]:=0;pre[s]:=s;
end;
procedure relax(u,v,w:integer);
begin
  if dis[u]+w<dis[v] then
    begin
      dis[v]:=dis[u]+w;
      pre[v]:=u;
    end
end;
function bellman_ford:boolean;
var
  i,j:longint;
begin
  for i:=1 to n do
    for j:=1 to e do
      with edges[j] do relax(a,b,w);
  for i:=1 to e do
    with edges[i] do
      if dis[a]+w<dis[b] then exit(false);
  exit(true)
end;
var
  i,o:longint;
begin
  readln(o);
  for i:=1 to o do
    begin
      init;
      if bellman_ford then writeln('No')
        else writeln('Yes')
    end;
end.
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值