【最短路】Party

 
party.in
4 8 2
1 2 4
1 3 2
1 4 7
2 1 1
2 3 5
3 1 2
3 4 4
4 2 3
party.out
10

 

看了题目都应该直到是最短路,只需两次即可

一次求出x到所有点的最短路 ,这个很好实现

第二次求出所有点到x的最短路,这个只需要在迭代更新的时候吧map[k,j]改成map[j,k]即可,这样就成了反向边,就可以求出所有点到x的最短路

program party;

var
  n,m,x:longint;
  map:array[0..1000+10,0..1000+10] of longint;
  dist:array[0..1000+10] of longint;//x 到 所有点的最短距离
  dis:array[0..1000+10] of longint;//所有点 到 x 的最短距离
  h:array[0..1000+10] of boolean;

procedure init;
begin
  assign(input,'party.in');
  assign(output,'party.out');
  reset(input);
  rewrite(output);
end;
procedure outit;
begin
  close(input);
  close(output);
  halt;
end;

procedure readdata;
var
  i,xx,yy:longint;
begin
  read(n,m,x);
  fillchar(map,sizeof(map),$7);
  for i:=1 to m do
    read(xx,yy,map[xx,yy]);
end;

procedure dij;
var
  i,j,k,min:longint;
begin
  for i:=1 to n do
  begin
    //find min
    min:=maxlongint; k:=0;
    for j:=1 to n do
      if (not h[j])and(min>dist[j]) then
      begin
        min:=dist[j];k:=j;
      end;
    //color it
    h[k]:=true;
    //renew
    for j:=1 to n do
    begin
      if (not h[j])and(dist[j]>dist[k]+map[k,j]) then
        dist[j]:=dist[k]+map[k,j];
    end;
  end;
end;

procedure dijs;
var
  i,j,k,min:longint;
begin
  for i:=1 to n do
  begin
    //find min
    min:=maxlongint;k:=0;
    for j:=1 to n do
      if (not h[j])and(min>dis[j]) then
      begin
        min:=dis[j];k:=j;
      end;
    //color it
    h[k]:=true;
    //renew
    for j:=1 to n do
      if (not h[j])and(dis[j]>dis[k]+map[j,k]) then
        dis[j]:=dis[k]+map[j,k];
  end;
end;

procedure main;
var
  i,sum,max:longint;
begin
  {//O(n3)的算法
  for k:=1 to n do
    for i:=1 to n do
      for j:=1 to n do
        if map[i,j]>map[i,k]+map[k,j] then
          map[i,j]:=map[i,k]+map[k,j];
  for i:=1 to n do dist[i]:=map[i,x]+map[x,i];
  dist[x]:=0;
  max:=0;
  for i:=1 to n do
    if max<dist[i] then max:=dist[i];
  //for i:=1 to n do write(dist[i],' '); writeln;
  writeln(max);}
  
  fillchar(dist,sizeof(dist),$7);
  fillchar(h,sizeof(h),0);
  dist[x]:=0;
  dij;//求 x 到 所有点 的最短路径
  //for i:=1 to n do write(dist[i],' ');writeln;

  fillchar(dis,sizeof(dis),$7);
  fillchar(h,sizeof(h),0);
  dis[x]:=0;
  dijs;//求 所有点 到 x 的最短路径
  //for i:=1 to n do write(dis[i],' ');writeln;
  
  max:=0;
  for i:=1 to n do
  begin
    if i=x then continue;
    sum:=dist[i]+dis[i];
    if max<sum then max:=sum;
  end;
  writeln(max);
end;

begin
  init;
  readdata;
  main;
  outit;
end.

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值