Codeforces Round #349 (Div. 2) D. World Tour (最短路)
题目链接:http://codeforces.com/contest/667/problem/D
给你一个有向图,dis[i][j]表示i到j的最短路,让你求dis[u][i] + dis[i][j] + dis[j][v]的最大值,其中u i j v互不相同。
先用优先队列的dijkstra预处理出i到j的最短距离(n^2 logn)。(spfa也可以做)
然后枚举4个点的中间两个点i j,然后枚举与i相连节点的最短路dis[u][i](只要枚举最长的3个就行了),接着枚举与j相连节点的最短路dis[j][v](同理也是枚举最长的3个就行了),复杂度为9*n^2。
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int MAXN = 5010; 4 typedef pair <int , int> P; 5 struct data { 6 int to , next; 7 }edge[MAXN]; 8 int head[MAXN] , cnt , dis[MAXN][MAXN] , INF = 1e9; 9 vector <P> G[MAXN] , RG[MAXN]; 10 11 inline void add(int u , int v) { 12 edge[cnt].next = head[u]; 13 edge[cnt].to = v; 14 head[u] = cnt++; 15 } 16 17 bool judge(int x1 , int x2 , int x3 , int x4) { 18 if(x1 == x2 || x1 == x3 || x1 == x4 || x2 == x3 || x2 == x4 || x3 == x4) 19 return false; 20 return true; 21 } 22 23 void dijkstra(int s) { 24 dis[s][s] = 0; 25 priority_queue <P , vector<P> , greater<P> > que; 26 while(!que.empty()) { 27 que.pop(); 28 } 29 que.push(P(0 , s)); 30 while(!que.empty()) { 31 P temp = que.top(); 32 que.pop(); 33 int u = temp.second; 34 if(dis[s][u] < temp.first) 35 continue; 36 for(int i = head[u] ; ~i ; i = edge[i].next) { 37 int v = edge[i].to; 38 if(dis[s][v] > dis[s][u] + 1) { 39 dis[s][v] = dis[s][u] + 1; 40 que.push(P(dis[s][v] , v)); 41 } 42 } 43 } 44 } 45 46 int main() 47 { 48 memset(head , -1 , sizeof(head)); 49 cnt = 0; 50 int n , m , u , v; 51 scanf("%d %d" , &n , &m); 52 for(int i = 1 ; i <= n ; i++) { 53 for(int j = 1 ; j <= n ; j++) { 54 dis[i][j] = INF; 55 } 56 } 57 while(m--) { 58 scanf("%d %d" , &u , &v); 59 add(u , v); 60 } 61 for(int i = 1 ; i <= n ; i++) { 62 dijkstra(i); 63 for(int j = 1 ; j <= n ; j++) { 64 if(dis[i][j] != INF) { 65 G[i].push_back(P(dis[i][j] , j)); 66 RG[j].push_back(P(dis[i][j] , i)); 67 } 68 } 69 } 70 for(int i = 1 ; i <= n ; i++) { 71 sort(G[i].begin() , G[i].end()); 72 sort(RG[i].begin() , RG[i].end()); 73 } 74 int r1 , r2 , r3 , r4 , Max = -1; 75 for(int i = 1 ; i <= n ; i++) { 76 for(int j = 1 ; j <= n ; j++) { 77 if(i == j || dis[i][j] == INF) 78 continue; 79 for(int x = RG[i].size() - 1 ; x >= max(int(RG[i].size() - 4) , 0) ; x--) { 80 for(int y = G[j].size() - 1 ; y >= max(int(G[j].size() - 4) , 0) ; y--) { 81 int xx = RG[i][x].second , yy = G[j][y].second; 82 if(dis[i][j] + dis[xx][i] + dis[j][yy] >= Max && judge(i , j , xx , yy)) { 83 r1 = xx , r2 = i , r3 = j , r4 = yy; 84 Max = dis[i][j] + dis[xx][i] + dis[j][yy]; 85 } 86 } 87 } 88 } 89 } 90 printf("%d %d %d %d\n" , r1 , r2 , r3 , r4); 91 }