1. 程式人生 > >10.5比賽 T3

10.5比賽 T3

mem 最長 display 這樣的 測試 hid () iostream 包含

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

10.5比賽 T3