2016计蒜之道复赛A 百度地图的实时路况

百度地图的实时路况功能相当强大,能方便出行的人们避开拥堵路段。一个地区的交通便捷程度就决定了该地区的拥堵情况。假设一个地区有 nnn 个观测点,编号从 111 到 nnn。定义 d(u,v,w)d(u,v,w)d(u,v,w) 为从 uuu 号点出发,严格不经过 vvv 号点,最终到达 www 号点的最短路径长度,如果不存在这样的路径,d(u,v,w)d(u,v,w)d(u,v,w) 的值为 −1-1−1。

那么这个地区的交通便捷程度 PPP 为:

P=∑1≤x,y,z≤n,x≠y,y≠zd(x,y,z)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≠z??d(x,y,z)

现在我们知道了该地区的 nnn 个点,以及若干条有向边,求该地区的交通便捷程度 PPP。

输入格式

第一行输入一个正整数 n(4≤n≤300)n(4 \leq n \leq 300)n(4≤n≤300),表示该地区的点数。

接下来输入 nnn 行,每行输入 nnn 个整数。第 iii 行第 jjj 个数 Gi,j(−1≤Gi,j≤10000;Gi,i=0)G_{i,j}(-1 \leq G_{i,j} \leq 10000;G_{i,i} = 0)G?i,j??(−1≤G?i,j??≤10000;G?i,i??=0) 表示从 iii 号点到 jjj 号的有向路径长度。如果这个数为 −1-1−1,则表示不存在从 iii 号点出发到 jjj 号点的路径。

输出格式

输出一个整数,表示这个地区的交通便捷程度。

样例输入

4
0 1 -1 -1
-1 0 1 -1
-1 -1 0 1
1 -1 -1 0

样例输出

4

【题解】“Floyd 算法又叫 “插点法”注意到插点的顺序是无关紧要的我们可以分治:令 solve(l, r) 表示处理区间 [l, r] 的询问取 mid = (l + r) / 2把 [l, mid] 的点插入,递归 solve(mid + 1, r);把 [mid + 1, r] 的点插入,递归 solve(l, mid);递归到叶子的时候,回答询问复杂度 O(N^3\log N),只需注意到每个点会被插 O(\log N) 次”—— 吕欣

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cstdlib>
 5 #include <queue>
 6 #include <vector>
 7 #define max(a, b) ((a) > (b) ? (a) : (b))
 8 #define min(a, b) ((a) < (b) ? (a) : (b))
 9
10 inline void read(int &x)
11 {
12     x = 0;char ch = getchar(), c = ch;
13     while(ch < ‘0‘ || ch > ‘9‘)c = ch, ch = getchar();
14     while(ch <= ‘9‘ && ch >= ‘0‘)x = x * 10 + ch - ‘0‘, ch = getchar();
15     if(c == ‘-‘)x = -x;
16 }
17
18 const int INF = 0x3f3f3f3f;
19 const int MAXN = 300 + 10;
20
21 int g[MAXN][MAXN],n;
22 long long ans;
23
24 void solve(int l, int r)
25 {
26     if(l == r)
27     {
28         for(register int i = 1;i <= n;++ i)
29         {
30             if(l == i) continue;
31             for(register int j = 1;j <= n;++ j)
32             {
33                 if(r == j) continue;
34                 if(g[i][j] != INF)
35                     ans += g[i][j];
36                 else
37                     -- ans;
38             }
39         }
40         return;
41     }
42     int tmp[MAXN][MAXN];
43     for(register int i = 1;i <= n;++ i)
44         for(register int j = 1;j <= n;++ j)
45             tmp[i][j] = g[i][j];
46     int mid = (l + r) >> 1;
47     for(register int k = l;k <= mid;++ k)
48         for(register int i = 1;i <= n;++ i)
49             for(register int j = 1;j <= n;++ j)
50                 if(g[i][j] > g[i][k] + g[k][j])
51                     g[i][j] = g[i][k] + g[k][j];
52     solve(mid + 1, r);
53     for(register int i = 1;i <= n;++ i)
54         for(register int j = 1;j <= n;++ j)
55             g[i][j] = tmp[i][j];
56     for(register int k = mid + 1;k <= r;++ k)
57         for(register int i = 1;i <= n;++ i)
58             for(register int j = 1;j <= n;++ j)
59                 if(g[i][j] > g[i][k] + g[k][j])
60                     g[i][j] = g[i][k] + g[k][j];
61     solve(l, mid);
62     return;
63 }
64
65 int main()
66 {
67     read(n);
68     for(register int i = 1;i <= n;++ i)
69         for(register int j = 1;j <= n;++ j)
70         {
71             read(g[i][j]);
72             if(g[i][j] == -1)g[i][j] = INF;
73         }
74     solve(1, n);
75     printf("%lld", ans);
76     return 0;
77 }

Code


 
时间: 2024-11-10 21:29:12

2016计蒜之道复赛A 百度地图的实时路况的相关文章

(最短路)2017 计蒜之道 复赛 D. 百度地图导航

百度地图上有 nn 个城市,城市编号依次为 11 到 nn.地图中有若干个城市群,编号依次为 11 到 mm.每个城市群包含一个或多个城市:每个城市可能属于多个城市群,也可能不属于任何城市群. 地图中有两类道路.第一类道路是 城市之间的快速路,两个城市 u,vu,v 之间增加一条距离为 cc 的边:第二类道路是 城市群之间的高速路,连接两个城市群 a,ba,b,通过这条高速路,城市群 aa 里的每个城市与城市群 bb 里的每个城市之间两两增加一条距离为 cc 的边.图中所有边均为无向边. 你需要

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

链接:https://nanti.jisuanke.com/t/11217 奉上官方题解: 枚举 d(x , y , z) 中的 y,把 y 从这个图中删去,再求这时的全源最短路即可,使用 Floyd 算法来做上述过程. Floyd 算法可以是一个增量的过程,虽然第一维一般都是从 1枚举到 k但是这个枚举的顺序并不影响最后的结果. 所以如果可以预处理出对于每个点 y,只剩 y 没有在 Floyd 的第一维枚举到的矩阵,这个矩阵的值就是不经过 y 点的全源最短路. 所以使用分治,每一次把点集拆成两

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

题目链接:https://nanti.jisuanke.com/t/A1108 这道题还挺有意思的.让我对Floyd的了解又加深了一点. 首先我们重新审视Floyd这三重循环到底有什么用?第一层是枚举中间结点,第二三层是枚举路径起点和终点.那么是不是当第一层循环还没枚举到的点,此时的最短路就不会经过这这些点呢? 答案是肯定的.所以这道题也就可以做了. 题目是要求我们计算  第一层循环缺一个点的情况下  的所有最短路之和.我们当然可以枚举这个缺的点,那么时间复杂度是O(n^4).不能接受. 那么我

百度地图的实时路况 2016 计蒜之道 复赛

https://nanti.jisuanke.com/t/A1108 way1: 应该很多同学的做法都是对于每次y,每次x,dijkstra+堆优化 n^2 * nlogn 其实log(300)很小... way2: 题解方法真心优秀!!! cdq分治 有助于理解floyd:每次加入一个可以使用的点,加n次,顺序可以调整 本题:对于每个y,仅仅是y点不能使用 每次计算1/2,cdq剩下的1/2(left,right分别来一次),直到只剩下一个数,这个点不用于求最短路.所有点都有且仅有一次出现“只

2018 计蒜之道复赛 贝壳找房魔法师顾问(并查集+dfs判环)

贝壳找房在遥远的传奇境外,找到了一个强大的魔法师顾问.他有 22 串数量相同的法力水晶,每个法力水晶可能有不同的颜色.为了方便起见,可以将每串法力水晶视为一个长度不大于 10^5105,字符集不大于 10^5105 的字符串.现在魔法师想要通过一系列魔法使得这两个字符串相同.每种魔法形如 (u,\ v),\ u,\ v \le 10^5(u, v), u, v≤105,可以将一个字符 uu改成一个字符 vv,并且可以使用无限次.出于种种原因,魔法师会强行指定这两个串能否进行修改. 若失败输出 -

百度地图的实时路况

百度地图的实时路况功能相当强大,能方便出行的人们避开拥堵路段.一个地区的交通便捷程度就决定了该地区的拥堵情况.假设一个地区有 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 \ne

2017 计蒜之道 复赛 Windows画图+百度地图导航

因为没有休息好, 打着很异常难受的一场比赛,坚持了一个半小时就撤了. Windows画图:签到题,没什么说的. #include<cstdio> #include<cstdlib> #include<cstring> #include<string> #include<algorithm> #include<iostream> #include<queue> #include<map> #include<

贝壳找房魔法师顾问 2018 计蒜之道 复赛

https://nanti.jisuanke.com/t/A1725 V&V 无向图 强连通图 每个子图,n个点,选择n-1条,使互相连接 因为目标点x->点y,可以改为点y->点x V&C 弱连通图(将有向图的所有的有向边替换为无向边,所得到的图称为原图的基图.如果一个有向图的基图是连通图,则有向图是弱连通图.) 1.一个弱连通子图,它里面的点与该弱连通子图外的点与没有关系,可以单独处理 2.弱连通子图里,一个点,必有另外点与之相邻,包括入和出 3.若弱连通子图里有环,则无论

2017计蒜之道复赛 百度地图导航

分析:这道题本质就是很简单的最短路问题,但是如果连边用O(n^2)的暴力会直接TLE掉,连一条边的复杂度是减少不了了,那么能不能减少连边的数量呢? 我们可以设置一个中间点p,假设a中的所有点要到b中去,则从a向p连一条有向边,p向b连一条有向边,可是这样权值不好办啊,那么我们把每个城市圈当作一个中心点,这样从a连向a',a'连向b',b'连向b,除了中间这条边以外的边权值都是0,但是我也有可能从b走向a啊,那么a到a'的两条边的边权都是0,这样会陷入死循环啊? 解决方法很简单,我们把每个中心点拆