CSP 201712-4 行车路线 迪杰斯特正解
引入
博博在做数据结构课设的时候,一开始用一个正常的dij去做这个题,也在CCF官网测试Accept,但在后来的思考中发现这个题并没有这么简单。
PS:如果您是用的dij求解此题,可以试一组样例
4 5
1 1 2 1
1 2 3 1
1 3 4 3
0 1 2 5
0 1 3 100
正确答案:21
.
所谓正解
目前在网络上对于此题的题解大体分为两类
- spaf
- dij
①spfa
对于网络上的第一种spaf解法并没有什么问题,复杂度O(n*m),但常数也不小,能成功通过此题.
②dij
但对于第二种dij的题解,目前我还没有发现一篇正解(也可能是我没发现,轻喷) 包括在CCF上AC的代码,也一样有问题(CCF数据水得不行)。大多数代码是利用局部最优解去求解全局最优解,这将使上面说到的那个输入的结果为25。
.
dij写法的修改
我们前面提到,目前网络上大多数dij写法都是利用局部最优解去求解全局最优解,不合理在于对于一个点v的最短路径不一定就是其他点的最短路径延申而来,二dij算法的思想就是这样,导致出现错误。所以我们如果一定要用dij写出正解,就要使其符合dij的基本思想。所以我们要对边进行一些处理才行 因为我们到达v点的最短路的最后一条路是大路和小路中的一条,但小路的选择会影响v点出的边的权值,所以我们为了使每一条边独立,我们就把所有的小路处理为一条条独立的路。 例如edge(1,2)=1,edge(2,3)=1,那么我们就再生成一个边edge(1,3)=4,这样我们以后就不用再考虑相邻小路的权值处理问题,这里我们可以使用Floyd来完成 ,因为n最大只有500,所以把所有小路合并后最多也只会生成25000条新路,这也是不会对我们的复杂度产生太大影响, 剩下的我们只需要对旧路+新路一起求最短路,但要注意不能让两条新路相邻,因为两条新路相邻的cost应为另一条长的新路的cost,所以我们需要用一个二维的len去做一次dij即可。
100代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll inf = 0x3f3f3f3f3f3f3f3f;
template <typename T> class Graph
{public:struct edge{int to;T data;edge *next;};Graph(int n);~Graph();bool addedge(int s,int t,T data);ll solve();private:edge **firstedge;int size;
};template <typename T>
Graph<T>::Graph(int n)
{firstedge=new edge*[n+1];for(int i=1;i<=n;i++)firstedge[i]=NULL;size=n;
}template <typename T>
Graph<T>::~Graph()
{for(int i=1;i<=size;i++){edge *p=firstedge[i];while(p){edge *tmp=p;p=p->next;delete tmp;}}delete[] firstedge;
}template <typename T>
bool Graph<T>::addedge(int s,int t,T data)
{if(s<1||s>size||t<1||t>size)return false;edge *p=new edge;p->to=t;p->data=data;p->next=firstedge[s];firstedge[s]=p;return true;
}template <typename T>
ll Graph<T>::solve()
{ll *len[2];len[0]=new ll[size+1];len[1]=new ll[size+1];for(int i=1;i<=size;i++)len[0][i]=len[1][i]=inf;len[0][1]=0;priority_queue<pair<pair<ll,int>,int>,vector<pair<pair<ll,int>,int> >,greater<pair<pair<ll,int>,int> > > que;que.push(make_pair(make_pair(0,0),1));while(!que.empty()){int c=que.top().first.first;int lastop=que.top().first.second;int v=que.top().second;que.pop();if(len[lastop][v]!=c)continue;edge *p=firstedge[v];while(p){if(p->data.second==0){if(len[0][p->to]>c+p->data.first){len[0][p->to]=c+p->data.first;que.push(make_pair(make_pair(len[0][p->to],0),p->to));}}else if(lastop==0){if(len[1][p->to]>c+p->data.first){len[1][p->to]=c+p->data.first;que.push(make_pair(make_pair(len[1][p->to],1),p->to));}}p=p->next;}}return min(len[0][size],len[1][size]);
}
int main()
{int n,m;scanf("%d%d",&n,&m);Graph<pair<ll,int> >g(n);int op,s,t;ll cost;ll len[n+1][n+1];for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)len[i][j]=inf;for(int i=1;i<=m;i++){scanf("%d%d%d%lld",&op,&s,&t,&cost);if(op==0){g.addedge(s,t,make_pair(cost,op));g.addedge(t,s,make_pair(cost,op));}else{len[s][t]=min(len[s][t],cost);len[t][s]=min(len[t][s],cost);}}for(int k=1;k<=n;k++)for(int i=1;i<=n;i++)for(int j=i;j<=n;j++)len[i][j]=min(len[i][j],len[i][k]+len[k][j]);for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)if(i!=j&&len[i][j]!=inf)g.addedge(i,j,make_pair(len[i][j]*len[i][j],1));printf("%lld\n",g.solve());return 0;
}
CSP 201712-4 行车路线 迪杰斯特正解相关推荐
- CSP认证:行车路线
问题描述 大致思路: 最短路+拆点 显然,本题是一道与图论当中最短路有关的问题,因此考虑使用SPFA / dijkstra等算法.观察本题数据规模和约定,部分测试数据不存在小道,就转化为了经典的最短路 ...
- CSP认证201712-4 行车路线[C++题解]:单源最短路变型、拆点、好题!
文章目录 题目解答 题目链接 题目解答 来源:acwing 分析: 题目给定所有答案不超过1e6,其实也就保证了连续小路的长度不超过1000(1000的平方就是1e6).这样我们就可以在题目给定的条件 ...
- CSP 201712-4 行车路线(100)
CSP 201712-4 行车路线(100) 问题描述 小明和小芳出去乡村玩,小明负责开车,小芳来导航. 小芳将可能的道路分为大道和小道.大道比较好走,每走1公里小明会增加1的疲劳度.小道不好走,如果 ...
- CSP第十二次认证 行车路线 拆点
这道题的关键是如何解决连续小路的情况,因为题目保证答案不超过1e6,说明小路的连续长度不超过1000,给了我们提示,可以将点拆分为两个属性,一个是点的序号,另一个则是最后一段连续小路的长度,所以我们的 ...
- CCF CSP 行车路线 java 201712_4
CCF CSP 行车路线 java 201712_4 问题描述 小明和小芳出去乡村玩,小明负责开车,小芳来导航. 小芳将可能的道路分为大道和小道.大道比较好走,每走1公里小明会增加1的疲劳度.小道不好 ...
- 行车路线(改)(图的应用)
写在前面:仅为个人代码/总结,未必标准,仅供参考!如有错误,还望指出交流,共同进步! 行车路线 [问题描述] 小明和小芳出去乡村玩,小明负责开车,小芳来导航. 小芳将可能的道路分为大道和小道.大道比较 ...
- 数据结构——行车路线规划(大路小路)
数据结构课程设计 行车路线(图) 小明和小芳出去乡村玩,小明负责开车,小芳来导航. 小芳将可能的道路分为大道和小道.大道比较好走,每走1公里小明会增加1的疲劳度.小道不好走,如果连续走小道,小明的疲劳 ...
- *11.迪杰斯克拉算法
概念 迪杰斯克拉算法是用来求单源最短路径,计算一个节点到其他所有节点的最短路径.并且要求图中不存在负权边.(简单点讲就是最短路径上的任意两点都是最短路径,有点套娃的思想) 算法步骤: 1.首先把图的一 ...
- CCF201712-4 行车路线(最短路)
试题编号: 201712-4 试题名称: 行车路线 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 小明和小芳出去乡村玩,小明负责开车,小芳来导航. 小芳将可能的道路分为大道和 ...
最新文章
- icns图标制作_PPT制作必备:这6个网站,帮你打造超强的图标素材库
- ZooKeeper集群安装
- ML之KMeans:利用KMeans算法对Boston房价数据集(两特征+归一化)进行二聚类分析
- 中科元素精准饮食治未病干预 李喜贵:签约华佗国药体系建立
- 5.26在网上看到的方法,实现图形缩放、对齐、图形修改后进行dirty check。(未实验过)...
- 国家邮政局公布一项数据 春节期间快递数量依旧很猛!
- jQuery 判断div是否shown
- 聊聊这两天刷屏的OpenAI新作,你注意到CLIP了吗
- [BZOJ1006]神奇的国度
- mysql用户角色权限表设计_用户角色权限设计(转)
- Python将多个excel文件合并为一个文件
- 不知道CAD坐标系,如何做到CAD与卫星影像无偏叠加?
- gmail上不去的解决方法(原)
- 下载安装linux RedHat
- 配置、账户-Windows 8学习总结 -by小雨
- 高德地图2----输入提示、关键字查询
- 阿里云天池——SQL训练计划_Task3
- HTML 常用特殊符号
- STM32F103C8T6工程文件的创建
- tomcat怎样配置多个域名
热门文章
- Daily English Dictation Number Six
- Final Cut Pro X v10.6.1(fcpx视频剪辑) 中文版已发布,支持M1intel处理器,支持monterey最新系统,功能介绍
- C51(DS18B20温度报警器)
- Arduion实验四 交通信号灯模块
- 【渝粤教育】国家开放大学2018年秋季 0700-21T中级会计实务(一) 参考试题
- [转]淘宝开放平台技术历程
- 阿里取消周报,打击低效加班!HR透露6大原因!
- 课工场与阿里云签订合作协议 共同培养云计算专业人才
- 让简历成为通往面试“绿卡”
- 前端低代码平台H5-Dooring使用文档