Party_纪中_1328

题目大意 

    N头牛要去参加一场在编号为x(1<=x<=n)的牛的农场举行的派对(1<=N<=1000,M(1<=m<=100000)条有向道路,每条路长ti(1<=ti<=100);
 每头牛都必须参加完派对后回到家,每头牛都会选择最短路径,求这n个牛的最短路径(一个来回)中最长的一条的长度。
 特别提醒:可能有权值不同的重边。

 

分析

  这一眼看上去就是一个最短路。

  注意,因为是有向图,所以从家到x农场的最短路和从x农场到家的最短路是不一样的。

  所以,只用先把x到其他点的最短路求出来,再把边反向链接,再求一次x到其他点的最短路。两次结果相加得数最大的,就是结果。

  

反思

  要设置好数组,jpwang就是因为数组没设好错的。

 

代码

const
  maxe=2000;
  maxv=200000;

type
  arr=record
    x,y,w:longint;
    next:longint;
end;

var
  a:array[1..maxv] of arr;
  ls:array[1..maxe] of longint;
  v,d,f,ans:array[1..maxe] of longint;
  i,j,k,w:longint;
  n,m,st:longint;
  nm,max:longint;

procedure spfa;
var
  i,j,k:longint;
  head,tail:longint;
begin
  head:=0; tail:=1;
  fillchar(v,sizeof(v),0);
  fillchar(d,sizeof(d),0);
  fillchar(f,sizeof(f),$7f);
  v[st]:=1;
  d[1]:=st;
  f[st]:=0;
  repeat
    head:=head+1;
    j:=d[head];
    i:=ls[j];
    while i<>0 do
      begin
        with a[i] do
          begin
            if f[x]+w<f[y]
              then
                begin
                  f[y]:=f[x]+w;
                  if v[y]=0
                    then
                      begin
                        tail:=tail+1;
                        v[y]:=1;
                        d[tail]:=y;
                      end;
                end;
            i:=next;
          end;
      end;
    v[j]:=0;
  until head=tail;
end;

procedure add(x,y,w:longint);
begin
  nm:=nm+1;
  a[nm].x:=x;
  a[nm].y:=y;
  a[nm].w:=w;
  a[nm].next:=ls[x];
  ls[x]:=nm;
end;

begin
  readln(n,m,st);
  fillchar(ls,sizeof(ls),0);
  for i:=1 to m do
    begin
      readln(j,k,w);
      add(j,k,w);
    end;
  spfa;
  for i:=1 to n do
    ans[i]:=f[i];
  fillchar(ls,sizeof(ls),0);
  for i:=1 to nm do
    begin
      with a[i] do
        begin
          j:=x;
          x:=y;
          y:=j;
          next:=ls[x];
          ls[x]:=i;
        end;
    end;
  spfa;
  for i:=1 to n do
    ans[i]:=f[i]+ans[i];
  max:=0;
  for i:=1 to n do
    if max<ans[i]
      then max:=ans[i];
  write(max);
end.


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值