zoukankan      html  css  js  c++  java
  • [计蒜客]百度地图的实时路况

    description

    给出有向图的点数(n)和邻接矩阵(G),
    求$$P=∑_{1≤x,y,z≤n,x≠y,y≠z}d(x,y,z)$$
    其中(d(x,y,z))表示从(x)不经过(y)(z)的最短路,如果无法到达则为(-1)

    data range

    [4≤n≤300,−1≤G_{i,j}≤10000,G_{i,i}=0 ]

    solution

    首先你要知道(floyed)的本质是枚举中转点

    那么不经过(y)点的最短路矩阵相当于使用除(y)以外的点作为中转点更新后的邻接矩阵

    于是考虑分治,递归到(l==r)时仅有节点(l)未被作为中转点
    那么在做到([l,r])时,使用([l,mid])更新([mid+1,r]),使用([mid+1,r])更新([l,mid])即可。

    Code

    #include<bits/stdc++.h>
    #include<algorithm>
    #include<iostream>
    #include<cstdlib>
    #include<iomanip>
    #include<cstring>
    #include<complex>
    #include<vector>
    #include<cstdio>
    #include<string>
    #include<bitset>
    #include<ctime>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<map>
    #include<set>
    #define Cpy(x,y) memcpy(x,y,sizeof(x))
    #define Set(x,y) memset(x,y,sizeof(x))
    #define FILE "a"
    #define mp make_pair
    #define pb push_back
    #define RG register
    #define il inline
    using namespace std;
    typedef unsigned long long ull;
    typedef vector<int>VI;
    typedef long long ll;
    typedef double dd;
    const int N=200010;
    const int M=1000010;
    const dd eps=1e-5;
    const int inf=2147483647;
    const ll INF=1ll<<60;
    const ll P=100000;
    il ll read(){
      RG ll data=0,w=1;RG char ch=getchar();
      while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
      if(ch=='-')w=-1,ch=getchar();
      while(ch<='9'&&ch>='0')data=data*10+ch-48,ch=getchar();
      return data*w;
    }
    
    il void file(){
      srand(time(NULL)+rand());
      freopen(FILE".in","r",stdin);
      freopen(FILE".out","w",stdout);
    }
    
    int n;ll ans,g[20][305][305];
    void divide(int l,int r,int d){
      if(l==r){
        for(RG int i=1;i<=n;i++)
          for(RG int j=1;j<=n;j++)
    	if(i!=l&&j!=l)ans+=g[d-1][i][j];
        return;
      }
      
      RG int mid=(l+r)>>1;
      
      memcpy(g[d],g[d-1],sizeof(g[d]));
      for(RG int k=mid+1;k<=r;k++)
        for(RG int i=1;i<=n;i++)
          if(k!=i)
    	for(RG int j=1;j<=n;j++)
    	  if(k!=j&&i!=j&&g[d][i][k]!=-1&&g[d][k][j]!=-1)
    	    if(g[d][i][j]==-1||g[d][i][j]>g[d][i][k]+g[d][k][j])
    	      g[d][i][j]=g[d][i][k]+g[d][k][j];
      divide(l,mid,d+1);
      
      memcpy(g[d],g[d-1],sizeof(g[d]));
      for(RG int k=l;k<=mid;k++)
        for(RG int i=1;i<=n;i++)
          if(k!=i)
    	for(RG int j=1;j<=n;j++)
    	  if(k!=j&&i!=j&&g[d][i][k]!=-1&&g[d][k][j]!=-1)
    	    if(g[d][i][j]==-1||g[d][i][j]>g[d][i][k]+g[d][k][j])
    	      g[d][i][j]=g[d][i][k]+g[d][k][j];
      divide(mid+1,r,d+1);
    }
    
    int main()
    {
      n=read();
      for(RG int i=1;i<=n;i++)
        for(RG int j=1;j<=n;j++)
          g[0][i][j]=read();
      divide(1,n,1);
      printf("%lld
    ",ans);
      return 0;
    }
    
    
  • 相关阅读:
    S2dao 简单Demo(转)
    Iphone SDK textField 打开和关闭键盘
    s2dao 入门知识2
    Eclipse tomcat Web页面调试
    s2dao 入门知识1
    java 面试
    Iphone SDK ActionSheet 在当前窗口弹出时间选择
    杭电2044
    杭电2076
    杭电2077
  • 原文地址:https://www.cnblogs.com/cjfdf/p/9703587.html
Copyright © 2011-2022 走看看