百度地图的实时路况
百度地图的实时路况功能相当强大,能方便出行的人们避开拥堵路段。一个地区的交通便捷程度就决定了该地区的拥堵情况。假设一个地区有 nn 个观测点,编号从 11 到 nn。定义 d(u,v,w)d(u,v,w) 为从 uu 号点出发,严格不经过 vv 号点,最终到达 ww 号点的最短路径长度,如果不存在这样的路径,d(u,v,w)d(u,v,w) 的值为 -1−1。
那么这个地区的交通便捷程度 PP 为:
P = \sum_{1 \leq x,y,z \leq n , x \neq y , y \neq z}{d(x,y,z)}P=∑1≤x,y,z≤n,x=y,y=zd(x,y,z)
现在我们知道了该地区的 nn 个点,以及若干条有向边,求该地区的交通便捷程度 PP。
输入格式
第一行输入一个正整数 n(4 \leq n \leq 300)n(4≤n≤300),表示该地区的点数。
接下来输入 nn 行,每行输入 nn 个整数。第 ii 行第 jj 个数 G_{i,j}(-1 \leq G_{i,j} \leq 10000;G_{i,i} = 0)Gi,j(−1≤Gi,j≤10000;Gi,i=0) 表示从 ii 号点到 jj 号的有向路径长度。如果这个数为 -1−1,则表示不存在从 ii 号点出发到 jj号点的路径。
输出格式
输出一个整数,表示这个地区的交通便捷程度。
样例输入
4 0 1 -1 -1 -1 0 1 -1 -1 -1 0 1 1 -1 -1 0
样例输出
4
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 305; const ll mod = 1e9 + 7; int n; int dis[maxn][maxn]; inline ll solve(int l,int r){ ll res=0; if(l==r){ for(register int i=1;i<=n;++i){ for(register int j=1;j<=n;++j){ if(i!=l&&j!=l){ res+=dis[i][j]; } } } return res; } int pre[maxn][maxn]; int mid=l+(r-l>>1); memcpy(pre,dis,sizeof(dis)); for(register int k=mid+1;k<=r;++k){ for(register int i=1;i<=n;++i){ if(i==k)continue; for(register int j=1;j<=n;++j){ if(i==j||k==j)continue; if(~dis[i][k]&&~dis[k][j]) { if (~dis[i][j]) { dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]); } else { dis[i][j] = dis[i][k] + dis[k][j]; } } } } } res+=solve(l,mid); memcpy(dis,pre,sizeof(pre)); for(register int k=l;k<=mid;++k){ for(register int i=1;i<=n;++i){ if(k==i)continue; for(register int j=1;j<=n;++j){ if(k==j||i==j)continue; if(~dis[i][k]&&~dis[k][j]) { if (~dis[i][j]) { dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]); } else { dis[i][j] = dis[i][k] + dis[k][j]; } } } } } res+=solve(mid+1,r); memcpy(dis,pre,sizeof(pre)); return res; } int main() { #ifndef ONLINE_JUDGE freopen("1.txt", "r", stdin); #endif scanf("%d",&n); for(register int i=1;i<=n;++i){ for(register int j=1;j<=n;++j){ scanf("%d",&dis[i][j]); } } printf("%lld",solve(1,n)); return 0; }