算法:分治+floyd_计蒜之道复赛A题 百度地图的实时路况
来源:互联网 发布:贱人软件5.9破解 编辑:程序博客网 时间:2024/05/16 23:48
题目:
百度地图的实时路况功能相当强大,能方便出行的人们避开拥堵路段。一个地区的交通便捷程度就决定了该地区的拥堵情况。假设一个地区有 n 个观测点,编号从 1 到 n。定义 d(u,v,w) 为从 u号点出发,严格不经过 v 号点,最终到达 ww 号点的最短路径长度,如果不存在这样的路径,d(u,v,w) 的值为 -1。
那么这个地区的交通便捷程度 P 为:
现在我们知道了该地区的 n 个点,以及若干条有向边,求该地区的交通便捷程度 P。
输入格式
第一行输入一个正整数
接下来输入 n 行,每行输入 n 个整数。第 i 行第 j 个数
输出格式
输出一个整数,表示这个地区的交通便捷程度。
样例输入
4
0 1 -1 -1
-1 0 1 -1
-1 -1 0 1
1 -1 -1 0
样例输出
4
一开始使用枚举来Floyd最短路计算,复杂度O(n^4),超时,确实没招,搜答案,发现了:
计蒜之道复赛A题 百度地图的实时路况(分治+floyd)
计蒜客 百度地图的实时路况
看了半天才整明白,其思想是减少不必要的重复计算,Floyd算法是将每个点依次加入路径中进行计算最短路,题目中是求依次去掉一个点时其它任意两点最短路之和,如果枚举,那么就是每次去掉一个点,对剩余点Floyd求最短路,这其实会造成很大的浪费,比如你在去掉第一个点和第二个点时,floyd算法中依次将除了这两个点之外的其余点纳入求最短路就是重复了一次,因此可以将重复的工作结果先保存下来,下次用时不用再次计算,这就是分治的思想。
具体到本题,可以将所有点分两部分,前半部分加入进行Floyd最短路计算后,将这部分结果保存用于后半部分的求解,若要对前半部分求解,需后半部分加入Floyd最短路后保存结果供前半部分使用;然后对此递归分治,直到只剩一个点时,其余点都已加入进行了Floyd最短路计算,相当于去掉这个点求Floyd,按题目中公式求和即可。
借鉴前人代码,重新整理了下,更清晰些:
#include <iostream>
#include <stdlib.h>
using namespace std;
int iMem(0);
long long iFluid(0); // 防止溢出;
int num(0);
struct dist
{
long long distance[301][301];
void addPointCal(int k)
{
for(int i=1; i<=num; i++)
for(int j=1; j<=num; j++)
{
if(distance[i][k]!=-1&&distance[k][j]!=-1)
if(distance[i][j]==-1||distance[i][j]>distance[i][k]+distance[k][j])
distance[i][j]=distance[i][k]+distance[k][j];
}
};
};
dist floydDist[10];
void divideConquer(int iRes,int left,int right)
{
//cout<<"divideConquer("<<iRes<<","<<left<<","<<right<<") ";
if(left==right)
{
for(int i=1; i<=num; i++)
{
if(i==left) continue;
for(int j=1; j<=num; j++)
{
if(j==left) continue;
iFluid+=floydDist[iRes].distance[i][j];
}
}
//cout<<"divideConquer("<<iRes<<","<<left<<","<<right<<") return"<<endl;
return;
}
int mid=(left+right)>>1;
iMem=iRes+1;
floydDist[iMem]=floydDist[iRes];
for(int i=left; i<=mid; i++)
floydDist[iMem].addPointCal(i);
//cout<<"floydDist["<<iMem<<"]:add("<<left<<","<<mid<<") "<<endl;
divideConquer(iMem,mid+1,right);
floydDist[iMem]=floydDist[iRes];
for(int i=mid+1; i<=right; i++)
floydDist[iMem].addPointCal(i);
//cout<<"floydDist["<<iMem<<"]:add("<<mid+1<<","<<right<<") "<<endl;
divideConquer(iMem,left,mid);
iMem--;
//cout<<"divideConquer("<<iRes<<","<<left<<","<<right<<") return"<<endl;
}
int main()
{
cin>>num;
for(int i=1; i<=num; i++)
for(int j=1; j<=num; j++)
cin>>floydDist[0].distance[i][j];
divideConquer(0,1,num);
cout<<iFluid;
return iFluid;
}
- 算法:分治+floyd_计蒜之道复赛A题 百度地图的实时路况
- 计蒜之道复赛A题 百度地图的实时路况(分治+floyd)
- 2016计蒜之道 复赛 A. 百度地图的实时路况(cdq分治+floyd)
- 计蒜之道 2016复赛A 百度地图的实时路况 [floyd+分治]【图论】
- 【分治+Floyd】2016计蒜之道复赛A[百度地图的实时路况]题解
- [分治+floyed] 2016 计蒜之道 复赛 A 百度地图的实时路况
- [分治 floyed] 2016 计蒜之道 复赛 百度地图的实时路况
- 2016 计蒜之道 复赛 百度地图的实时路况 [Floyd][分治]
- [分治 Floyd] 计蒜之道2016复赛 .百度地图的实时路况
- 【Floyd+分治】计蒜客 百度地图的实时路况
- 计蒜之道复赛D题—— 百度地图导航
- 计蒜客 百度地图的实时路况
- 计蒜客 百度地图的实时路况
- 计蒜客 百度地图的实时路况
- 2016 计蒜之道 复赛 A
- 2017 计蒜之道 复赛 百度地图导航【思维+最短路】
- 2017计蒜之道复赛 百度地图导航 (最短路)
- [最短路] 2017 计蒜之道 复赛 D. 百度地图导航
- 继承中的同名成员变量和函数
- PHP修炼之路之学PHP不得不看的20条忠告建议
- 状态栏
- logstash Codec
- 自定义搜索框searchview
- 算法:分治+floyd_计蒜之道复赛A题 百度地图的实时路况
- JAVA学习笔记【java环境搭建01】
- 20160823模拟赛T2
- 设置窗口满屏 隐藏虚拟键盘
- SAP.CO.Standard Hierarchies
- 【Sqlserver】各种数据库的锁表和解锁操作
- React Native商城项目实战09 - 个人中心自定义cell
- 2016物联网版图:物联网奇点是否已经来临?
- 图片轮播器以及NSTimer的使用