zoukankan      html  css  js  c++  java
  • 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
    " , r1 , r2 , r3 , r4);
    91 }
  • 相关阅读:
    数据结构与算法习题总结——树结构
    SQL入门题集及学习笔记
    nlp入门系列笔记——阿里天池新闻文本新手赛
    linux一步一脚印--- ls -l 命令执行显示结果的每一列含义
    Python tuple元组---学习总结
    Python——列表深浅拷贝
    Python list列表---学习总结
    linux一步一脚印---mv命令
    linux一步一脚印---rm命令
    linux一步一脚印---cp命令
  • 原文地址:https://www.cnblogs.com/Recoder/p/5459646.html
Copyright © 2011-2022 走看看