引入

博博在做数据结构课设的时候,一开始用一个正常的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 行车路线 迪杰斯特正解相关推荐

  1. CSP认证:行车路线

    问题描述 大致思路: 最短路+拆点 显然,本题是一道与图论当中最短路有关的问题,因此考虑使用SPFA / dijkstra等算法.观察本题数据规模和约定,部分测试数据不存在小道,就转化为了经典的最短路 ...

  2. CSP认证201712-4 行车路线[C++题解]:单源最短路变型、拆点、好题!

    文章目录 题目解答 题目链接 题目解答 来源:acwing 分析: 题目给定所有答案不超过1e6,其实也就保证了连续小路的长度不超过1000(1000的平方就是1e6).这样我们就可以在题目给定的条件 ...

  3. CSP 201712-4 行车路线(100)

    CSP 201712-4 行车路线(100) 问题描述 小明和小芳出去乡村玩,小明负责开车,小芳来导航. 小芳将可能的道路分为大道和小道.大道比较好走,每走1公里小明会增加1的疲劳度.小道不好走,如果 ...

  4. CSP第十二次认证 行车路线 拆点

    这道题的关键是如何解决连续小路的情况,因为题目保证答案不超过1e6,说明小路的连续长度不超过1000,给了我们提示,可以将点拆分为两个属性,一个是点的序号,另一个则是最后一段连续小路的长度,所以我们的 ...

  5. CCF CSP 行车路线 java 201712_4

    CCF CSP 行车路线 java 201712_4 问题描述 小明和小芳出去乡村玩,小明负责开车,小芳来导航. 小芳将可能的道路分为大道和小道.大道比较好走,每走1公里小明会增加1的疲劳度.小道不好 ...

  6. 行车路线(改)(图的应用)

    写在前面:仅为个人代码/总结,未必标准,仅供参考!如有错误,还望指出交流,共同进步! 行车路线 [问题描述] 小明和小芳出去乡村玩,小明负责开车,小芳来导航. 小芳将可能的道路分为大道和小道.大道比较 ...

  7. 数据结构——行车路线规划(大路小路)

    数据结构课程设计 行车路线(图) 小明和小芳出去乡村玩,小明负责开车,小芳来导航. 小芳将可能的道路分为大道和小道.大道比较好走,每走1公里小明会增加1的疲劳度.小道不好走,如果连续走小道,小明的疲劳 ...

  8. *11.迪杰斯克拉算法

    概念 迪杰斯克拉算法是用来求单源最短路径,计算一个节点到其他所有节点的最短路径.并且要求图中不存在负权边.(简单点讲就是最短路径上的任意两点都是最短路径,有点套娃的思想) 算法步骤: 1.首先把图的一 ...

  9. CCF201712-4 行车路线(最短路)

    试题编号: 201712-4 试题名称: 行车路线 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 小明和小芳出去乡村玩,小明负责开车,小芳来导航. 小芳将可能的道路分为大道和 ...

最新文章

  1. icns图标制作_PPT制作必备:这6个网站,帮你打造超强的图标素材库
  2. ZooKeeper集群安装
  3. ML之KMeans:利用KMeans算法对Boston房价数据集(两特征+归一化)进行二聚类分析
  4. 中科元素精准饮食治未病干预 李喜贵:签约华佗国药体系建立
  5. 5.26在网上看到的方法,实现图形缩放、对齐、图形修改后进行dirty check。(未实验过)...
  6. 国家邮政局公布一项数据 春节期间快递数量依旧很猛!
  7. jQuery 判断div是否shown
  8. 聊聊这两天刷屏的OpenAI新作,你注意到CLIP了吗
  9. [BZOJ1006]神奇的国度
  10. mysql用户角色权限表设计_用户角色权限设计(转)
  11. Python将多个excel文件合并为一个文件
  12. 不知道CAD坐标系,如何做到CAD与卫星影像无偏叠加?
  13. gmail上不去的解决方法(原)
  14. 下载安装linux RedHat
  15. 配置、账户-Windows 8学习总结 -by小雨
  16. 高德地图2----输入提示、关键字查询
  17. 阿里云天池——SQL训练计划_Task3
  18. HTML 常用特殊符号
  19. STM32F103C8T6工程文件的创建
  20. tomcat怎样配置多个域名

热门文章

  1. Daily English Dictation Number Six
  2. Final Cut Pro X v10.6.1(fcpx视频剪辑) 中文版已发布,支持M1intel处理器,支持monterey最新系统,功能介绍
  3. C51(DS18B20温度报警器)
  4. Arduion实验四 交通信号灯模块
  5. 【渝粤教育】国家开放大学2018年秋季 0700-21T中级会计实务(一) 参考试题
  6. [转]淘宝开放平台技术历程
  7. 阿里取消周报,打击低效加班!HR透露6大原因!
  8. 课工场与阿里云签订合作协议 共同培养云计算专业人才
  9. 让简历成为通往面试“绿卡”
  10. 前端低代码平台H5-Dooring使用文档