10.5比赛 T3

T3.小 Z 爱旅行 (travel) )
放假了,小 Z 准备去郊外一些景点旅行。为此,它查明了学校附近的一些
景点和这些景点之间的一些单向道路。 国庆长假总共有 8 天, 但是小 Z 其中 4 天
都要训练,所以他打算挑选 4 个不同的景点,按照顺序从第一个景点开始,然后
依次前往第二、三个,最后到达第四个景点。小 Z 很懒,所以把设计线路的任务
交给了你。你当然没安好心啦,所以你想要设计的路线的长度最长。小 Z 很聪
明,总是会走最短的路径,现在请你设计这条路线吧。
小 Z 只根据路径经过的道路的条数判断路径的长短,在他眼中所有道路的
长度都相同。
[ [ 输入格式] ]
从 travel.in 中读取数据。
第一行两个数字 n,m,表示景点的数量和道路的数量。
接下来 m 行,每行两个整数 ui,vi,表示有一条从 ui 到 vi 的单向道路。
[ [ 输出格式] ]
输出包含 1 行 4 个整数,依次表示小 Z 要前往的 4 个景点。相邻景点间,前一
个景点必须有路径能够到达后一个景点, 数据保证一定存在这样的线路。 如果有
多个最长线路,你可以输出任意一个。
[ [ 样例输入] ]
8 9
1 2
2 3
3 4
4 1
4 5
5 6
6 7
7 8
8 5
[ [ 样例输出] ]
2 1 8 7
[ [ 样例解释] ]
2 到 1 的距离是 3,1 到 8 的距离是 7,8 到 7 的距离是 3,总距离 13。
可以证明这是一条距离最大的路线。
[ [ 数据范围与约定] ]
本题采用子任务制, 你只有通过同一子任务内的所有测试点才能得到这个测试点
对应的分数。
Subtask1: 包含 30Points 满足 n<=100
Subtask2: 包含 30Points 满足 n<=500
Subtask3: 包含 40Points 满足 n<=2000,m<=4000

思路:

先用bfs过一遍最短路,然后枚举中间两个数。

因为不能重复,所以要查找距离中间两个数最长的前三位数。

判断是否重复,就好了。

时间复杂度为O 9n^2.

代码:

  1 #include<iostream>
  2 #include<cstring>
  3 #include<cstdio>
  4 #include<cmath>
  5 using namespace std;
  6 const int I=1e9;
  7 int n,m,h,daan[4],dn;
  8 int f[2001],l[2001],b[2001][2001];
  9 int c[3][2001],d[3][2001];
 10 int cc[3][2001],dd[3][2001];
 11 struct sz
 12 {
 13     int t,w;
 14 }a[4001];
 15 void dy(int x,int y)
 16 {
 17     h++;
 18     a[h].t=y;
 19     a[h].w=f[x];
 20     f[x]=h;
 21     return;
 22 }
 23 void zj(int x,int y,int z)
 24 {
 25     if(z>d[0][x])
 26     {
 27         c[2][x]=c[1][x];
 28         d[2][x]=d[1][x];
 29         c[1][x]=c[0][x];
 30         d[1][x]=d[0][x];
 31         c[0][x]=y;
 32         d[0][x]=z;
 33     }
 34     else if(z>d[1][x])
 35     {
 36         c[2][x]=c[1][x];
 37         d[2][x]=d[1][x];
 38         c[1][x]=y;
 39         d[1][x]=z;
 40     }
 41     else if(z>d[2][x])
 42     {
 43         c[2][x]=y;
 44         d[2][x]=z;
 45     }
 46     return;
 47 }
 48 void zjj(int x,int y,int z)
 49 {
 50     if(z>dd[0][x])
 51     {
 52         cc[2][x]=cc[1][x];
 53         dd[2][x]=dd[1][x];
 54         cc[1][x]=cc[0][x];
 55         dd[1][x]=dd[0][x];
 56         cc[0][x]=y;
 57         dd[0][x]=z;
 58     }
 59     else if(z>dd[1][x])
 60     {
 61         cc[2][x]=cc[1][x];
 62         dd[2][x]=dd[1][x];
 63         cc[1][x]=y;
 64         dd[1][x]=z;
 65     }
 66     else if(z>dd[2][x])
 67     {
 68         cc[2][x]=y;
 69         dd[2][x]=z;
 70     }
 71     return;
 72 }
 73 int main()
 74 {
 75     //freopen("travel.in","r",stdin);
 76     //freopen("travel.out","w",stdout);
 77     int i,j,g,k;
 78     cin>>n>>m;
 79     memset(b,63,sizeof(b));
 80     for(i=1;i<=m;i++)
 81     {
 82         int x,y;
 83         cin>>x>>y;
 84         dy(x,y);
 85     }
 86     for(i=1;i<=n;i++)
 87     {
 88         int hh=1;
 89         l[hh]=i;
 90         b[i][i]=0;
 91         for(j=1;j<=hh;j++)
 92         {
 93             for(g=f[l[j]];g;g=a[g].w)
 94             {
 95                 if(b[i][l[j]]+1<b[i][a[g].t])
 96                 {
 97                     hh++;
 98                     l[hh]=a[g].t;
 99                     b[i][a[g].t]=b[i][l[j]]+1;
100                 }
101             }
102         }
103     }
104     for(i=1;i<=n;i++)
105     {
106         for(j=1;j<=n;j++)
107         {    
108             if(i!=j&&b[i][j]<I)
109             {
110                 zj(i,j,b[i][j]);
111                 zjj(j,i,b[i][j]);
112             }
113         }
114     }
115     for(i=1;i<=n;i++)
116     {
117         for(j=1;j<=n;j++)
118         {
119             if(i!=j&&b[i][j]<I)
120             {
121                 for(k=0;k<3;k++)
122                 {
123                     if(cc[k][i]!=j&&cc[k][i])
124                     {
125                         for(g=0;g<3;g++) 
126                         {
127                             if(c[g][j]!=i&&c[g][j]!=cc[k][i]&&c[g][j])
128                             {
129                                 if(dn<dd[k][i]+b[i][j]+d[g][j])
130                                 {
131                                     dn=dd[k][i]+b[i][j]+d[g][j];
132                                     daan[0]=cc[k][i];
133                                     daan[1]=i;
134                                     daan[2]=j;
135                                     daan[3]=c[g][j];
136                                 }
137                             }
138                         }
139                     }
140                 }
141             }
142         }
143     }
144     for(i=0;i<=3;i++)
145     {
146         cout<<daan[i]<<" ";
147     }
148     return 0;
149 }
View Code
原文地址:https://www.cnblogs.com/fenghhh/p/7631527.html