• 2016计蒜之道复赛 百度地图的实时路况 floyd+cdq分治


    链接:https://nanti.jisuanke.com/t/11217

    奉上官方题解:

    枚举 d(x , y , z) 中的 y,把 y 从这个图中删去,再求这时的全源最短路即可,使用 Floyd 算法来做上述过程

    Floyd 算法可以是一个增量的过程,虽然第一维一般都是从 1枚举到 k但是这个枚举的顺序并不影响最后的结果。

    所以如果可以预处理出对于每个点 y,只剩 y 没有在 Floyd 的第一维枚举到的矩阵,这个矩阵的值就是不经过 y 点的全源最短路。

    所以使用分治,每一次把点集拆成两半,先用前一半的点在 Floyd 算法中滚,再递归后一半点。

    然后回溯,用后一半的点在 Floyd 算法里滚,递归前一半的点。这样每个只有一个点的状态得到的就是只有这个点没有在 Floyd 算法里滚的矩阵。

    时间复杂度为 O(n^3​​logn)。

    吐槽:在写这个题以前,cdq分治只写过三维偏序模板题,整体二分的题写的很少,以后要应该多写一些

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <string>
    #include <stack>
    #include <vector>
    #include <map>
    #include <queue>
    #include <algorithm>
    #include <utility>
    using namespace std;
    typedef long long LL;
    const int N=305;
    const int INF=0x3f3f3f3f;
    int dp[25][N][N],n,mp[N][N];
    LL ret;
    void cpydp(int dep){
      for(int i=1;i<=n;++i)
        for(int j=1;j<=n;++j)
          dp[dep][i][j]=dp[dep-1][i][j];
    }
    void update(int dep,int l,int r){
      for(int k=l;k<=r;++k)
        for(int i=1;i<=n;++i)
          for(int j=1;j<=n;++j)
            if(dp[dep][i][j]>dp[dep][i][k]+dp[dep][k][j])
               dp[dep][i][j]=dp[dep][i][k]+dp[dep][k][j];
    }
    void cdq(int dep,int l,int r){
      if(l==r){
        for(int i=1;i<=n;++i)
          for(int j=1;j<=n;++j){
            if(i==l||j==l)continue;
            if(dp[dep][i][j]==INF)dp[dep][i][j]=-1;
            ret+=1ll*dp[dep][i][j];
          }
        return;
      }
      int m=l+r>>1;
      cpydp(dep+1),update(dep+1,m+1,r);
      cdq(dep+1,l,m);
      cpydp(dep+1),update(dep+1,l,m);
      cdq(dep+1,m+1,r);
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;++i)
          for(int j=1;j<=n;++j){
            scanf("%d",&dp[0][i][j]);
            if(dp[0][i][j]==-1)dp[0][i][j]=INF;
          }  
        cdq(0,1,n);
        cout<<ret<<endl;
        return 0;
    }
    View Code
  • 相关阅读:
    Hadoop2.2.0 注意事项
    为一个表增加一列,这个列能够自增加1
    商品推荐系统问题
    Android Service服务-(转)
    android实现通知栏消息
    【Android】状态栏通知Notification、NotificationManager详解(转)
    android调用邮件应用发送email
    有关WebView开发问题(转)
    Android开发把项目打包成apk-(转)
    对话框(单选)
  • 原文地址:https://www.cnblogs.com/shuguangzw/p/5643071.html
Copyright © 2020-2023  润新知