解题报告 聚会

1.        题目

聚会 (FTT

【问题描述】

S想要从某地出发去同学k的家中参加一个party,但要有去有回。他想让所用的时间尽量的短。但他又想知道从不同的点出发,来回的最短时间中最长的时间是多少,

这个任务就交给了你。

【输入格式】

第一行三个正整数n,m,k(n是节点个数,m是有向边的条数,k是参加聚会的地点编号)( 1 ≤ N ≤ 1000 ,1 ≤ M ≤ 100,000)

第二行..m+1行每行3个整数x,y,w 代表从x到y需要花w的时间(1 ≤ w≤ 100)

【输出格式】

   输出从不同的节点出发的最短时间中最长的时间。

【样例输入】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

 

2.        题目实质

其实这个东西就是一个最短路的模型。

3.        算法

我说是网络流......你信不?

废话,当然是最短路!

每个点到K节点的最短路 + K到对应的点的最短路

以除K以外的点到K的最短路反复的求就有了很多的冗余,会超时

可以思考从其他的点到K点的最短路等价于从K点出发使用反向边求到各个点的最短路

这样这道题就完美的解决了 ans=max{dis1[i][k]+dis2[i][k]}

4.        注意事项

注意,这个题是非常典型的需要正着求一遍,反着求一遍的最短路。

5.        代码

水水最短路 Leve

var

 n,m,k,i,j,ans:longint;

 x,y,len:longint;

 d:array[1..1000] of longint;

 sum:array[1..1000] of longint;

 map,mapp:array[1..1000,0..1000] of longint;

 ll,lll:array[1..1000,1..1000] of longint;

 q:array[1..1000000] of longint;

 v:array[1..1000] of boolean;

procedure spfa(x:longint);

 var

  i,l,r,temp:longint;

 begin

  filldword(d,sizeof(d)>>2,maxlongint>>1);

  fillchar(v,sizeof(v),false);

  v[x]:=true;

  l:=0; r:=1;

  d[x]:=0;

  q[1]:=x;

  while l<r do

   begin

    inc(l);

temp:=q[l];

v[temp]:=false;

for i:=1 to map[temp,0] do

 if d[map[temp,i]]>d[temp]+ll[temp,i] then

  begin

   d[map[temp,i]]:=d[temp]+ll[temp,i];

   if not v[map[temp,i]] then

    begin

 v[map[temp,i]]:=true;

 inc(r);

    q[r]:=map[temp,i];

end;

 end;

   end;

 end;

procedure spfa2(x:longint);

 var

  i,l,r,temp:longint;

 begin

  filldword(d,sizeof(d)>>2,maxlongint>>1);

  fillchar(v,sizeof(v),false);

  v[x]:=true;

  l:=0; r:=1;

  d[x]:=0;

  q[1]:=x;

  while l<r do

   begin

    inc(l);

temp:=q[l];

v[temp]:=false;

for i:=1 to mapp[temp,0] do

 if d[mapp[temp,i]]>d[temp]+lll[temp,i] then

  begin

   d[mapp[temp,i]]:=d[temp]+lll[temp,i];

   if not v[mapp[temp,i]] then

    begin

 v[mapp[temp,i]]:=true;

 inc(r);

    q[r]:=mapp[temp,i];

end;

 end;

   end;

 end;

begin

 assign(input,'party.in');

 assign(output,'party.out');

 reset(input);

 rewrite(output);

 readln(n,m,k);

 for i:=1 to m do

  begin

   readln(x,y,len);

   inc(map[x,0]);

   map[x,map[x,0]]:=y;

   ll[x,map[x,0]]:=len;

   inc(mapp[y,0]);

   mapp[y,mapp[y,0]]:=x;

   lll[y,mapp[y,0]]:=len;

  end;

 spfa(k);

 for i:=1 to n do

  sum[i]:=d[i];

 spfa2(k);

 for i:=1 to n do

  if i<>k then

   if d[i]<maxlongint>>1 then

    if sum[i]<maxlongint>>1 then

     if d[i]+sum[i]>ans then ans:=d[i]+sum[i];

 writeln(ans);

 close(input);

 close(output);

end.

 

 

 

 

 

原文地址:https://www.cnblogs.com/SueMiller/p/2207802.html