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 }