【CF666B】World Tour(贪心,最短路)

题意:给你一张有向图,叫你给出四个点的序列a,b,c,d,使得这四个点依次间的最短路之和最大。(4 ≤ n ≤ 3000, 3 ≤ m ≤ 5000) 

思路:O(n4)可用来对拍

        我们需要O(n2)级别的算法

        若枚举c,d,预处理出x到b比较远的3个x,d到y比较远的3个y,时间复杂度O(9n2)

        为什么是3个而不是2个?

        abc已枚举,若d的备选是ab就要GG,所以应该多一个备用,也就是三个点

  1 var c,d:array[1..3000,1..3,1..2]of longint;
  2     head,vet,next,b,flag,q,x,y:array[1..10000]of longint;
  3     dis:array[1..3000]of longint;
  4     save:array[1..3000,1..3000]of longint;
  5     n,m,tot,i,s1,s2,s3,s4,a1,b1,c1,d1,ans,j,k,s,p1,q1:longint;
  6 
  7 procedure add(a,b:longint);
  8 begin
  9  inc(tot);
 10  next[tot]:=head[a];
 11  vet[tot]:=b;
 12  head[a]:=tot;
 13 end;
 14 
 15 procedure bfs(x:longint);
 16 var t,w,e,u,v:longint;
 17 begin
 18  fillchar(b,sizeof(b),0);
 19  fillchar(dis,sizeof(dis),0);
 20  t:=1; w:=1; q[1]:=x; b[x]:=1; dis[x]:=0;
 21  while t<=w do
 22  begin
 23   u:=q[t]; inc(t);
 24   e:=head[u];
 25   while e<>0 do
 26   begin
 27    v:=vet[e];
 28    if b[v]=0 then
 29    begin
 30     dis[v]:=dis[u]+1;
 31     b[v]:=1;
 32     inc(w); q[w]:=v;
 33    end;
 34    e:=next[e];
 35   end;
 36  end;
 37 end;
 38 
 39 begin
 40  //assign(input,'1.in'); reset(input);
 41  //assign(output,'1.out'); rewrite(output);
 42  readln(n,m);
 43  for i:=1 to m do
 44  begin
 45   readln(x[i],y[i]);
 46   add(x[i],y[i]);
 47  end;
 48 
 49  for i:=1 to n do
 50  begin
 51   bfs(i);
 52   k:=1; s:=0;
 53   fillchar(flag,sizeof(flag),0);
 54   for j:=1 to n do
 55    if (flag[j]=0)and(dis[j]>s) then
 56    begin
 57     k:=j; s:=dis[j];
 58    end;
 59   flag[k]:=1; c[i,1,1]:=k; c[i,1,2]:=s;
 60   k:=1; s:=0;
 61   for j:=1 to n do
 62    if (flag[j]=0)and(dis[j]>s) then
 63    begin
 64     k:=j; s:=dis[j];
 65    end;
 66   flag[k]:=1; c[i,2,1]:=k; c[i,2,2]:=s;
 67   k:=1; s:=0;
 68   for j:=1 to n do
 69    if (flag[j]=0)and(dis[j]>s) then
 70    begin
 71     k:=j; s:=dis[j];
 72    end;
 73   flag[k]:=1; c[i,3,1]:=k; c[i,3,2]:=s; // x---->c[i] 1,2,3
 74   for j:=1 to n do save[i,j]:=dis[j];
 75  end;
 76 
 77  fillchar(head,sizeof(head),0);
 78  tot:=0;
 79  for i:=1 to m do add(y[i],x[i]);
 80 
 81  for i:=1 to n do
 82  begin
 83   bfs(i);
 84   k:=1; s:=0;
 85   fillchar(flag,sizeof(flag),0);
 86   for j:=1 to n do
 87    if (flag[j]=0)and(dis[j]>s) then
 88    begin
 89     k:=j; s:=dis[j];
 90    end;
 91   flag[k]:=1; d[i,1,1]:=k; d[i,1,2]:=s;
 92   k:=1; s:=0;
 93   for j:=1 to n do
 94    if (flag[j]=0)and(dis[j]>s) then
 95    begin
 96     k:=j; s:=dis[j];
 97    end;
 98   flag[k]:=1; d[i,2,1]:=k; d[i,2,2]:=s;
 99   k:=1; s:=0;
100   for j:=1 to n do
101    if (flag[j]=0)and(dis[j]>s) then
102    begin
103     k:=j; s:=dis[j];
104    end;
105   flag[k]:=1; d[i,3,1]:=k; d[i,3,2]:=s; // d[i] 1 2 3 ---->i
106  end;
107 
108  s1:=1; s2:=2; s3:=3; s4:=4; ans:=-maxlongint;
109  for b1:=1 to n do
110   for c1:=1 to n do
111    if save[b1,c1]>0 then
112    for p1:=1 to 3 do
113     for q1:=1 to 3 do
114     begin
115      d1:=c[c1,p1,1];
116      a1:=d[b1,q1,1];     //a1-->b1-->c1-->d1
117      if (a1<>b1)and(a1<>c1)and(a1<>d1)and(b1<>c1)and(b1<>d1)and(c1<>d1) then
118       if d[b1,q1,2]+c[c1,p1,2]+save[b1,c1]>ans then
119       begin
120        s1:=a1; s2:=b1; s3:=c1; s4:=d1;
121        ans:=d[b1,q1,2]+c[c1,p1,2]+save[b1,c1];
122       end;
123     end;
124  writeln(s1,' ',s2,' ',s3,' ',s4);
125 
126  //close(input);
127  //close(output);
128 end.
View Code
原文地址:https://www.cnblogs.com/myx12345/p/5524707.html