例题:

Time Limit: 1 second
Memory Limit: 128 MB
【问题描述】
在电视时代,没有多少人观看戏剧表演。Malidinesia古董喜剧演员意识到这一事实,他们想宣传剧院,尤其是古色古香的喜剧片。他们已经打印请帖和所有必要的信息和计划。许多学生被雇来分发这些请柬。每个学生志愿者被指定一个确切的公共汽车站,他或她将留在那里一整天,邀请人们参与。   这里的公交系统是非常特殊的:所有的线路都是单向的,连接两个站点。公共汽车离开起始点,到达目的地之后又空车返回起始点。  学生每天早上从总部出发,乘公交车到一个预定的站点邀请乘客。每个站点都被安排了一名学生。在一天结束的时候,所有的学生都回到总部。现在需要知道的是,学生所需的公交费用的总和最小是多少。

【输入格式】
第1行有两个整数n、m(1<=n,m<=1000000),n是站点的个数,m是线路的个数。 然后有m行,每行描述一个线路,包括3个整数,起始点,目的地和价格。 总部在第1个站点,价钱都是整数,且小于1000000000。
【输出格式】
输出一行,表示最小费用。
【数据规模】
Sample Input1
4 6
1 2 10
2 1 60
1 3 20
3 4 10
2 4 5
4 1 50

Sample Output1
210

【样例说明】
学生各自从总部被派遣到2,3,4站点,然后又回到总部
1-2-4-1:10+5+50=65
1-3-4-1:20+10+50=80
1-2-4-1:10+5+50=65
65+80+65=210
此题数据规模较大,需要使用较为高效的算法,此题不设小规模数据分数。

【题解】

这题的图算是比较的密集的图。如果用spfa的话。第一个点无法通过。而应该用dijkstra+堆优化来实现。
因为后者更擅长解决密集的图的问题。
做法是这样。
一开始输入图的时候,建一个正图和一个反图。
然后分别在正图和反图上做从起点1到其他点的最短路。
然后获取的dis[0][1..n],dis[1][1..n]分别表示在正图和反图上1到其他点的最短路。
最后答案累加dis[0][i]+disi;
难点在dijkstra的堆优化(堆操作)
->这里用multiset+它的upper_bound函数来实现堆优化;
注意重载判断的时候要把第二个关键字也照顾到,不然upper_bound会失效
获取multiset的头结点的地址
设h为一个结构体multiset

__typeof(h.begin()) c=begin();
c就是头结点的地址;
然后x=(*c)就是头元素;
则可以直接访问结构体里的元素了
x.name
x.point
什么的.
upper_bound出来的类型也一样;
也是__typeof(h.begin())

【完整代码】

#include <bits/stdc++.h>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define LL long long
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define rei(x) scanf("%d",&x)
#define rel(x) scanf("%I64d",&x)typedef pair<int,int> pii;
typedef pair<LL,LL> pll;const int MAXN = 1e6+10;
const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
const double pi = acos(-1.0);vector <LL> w[2][MAXN];
vector <int> g[2][MAXN];
__int64 dis[2][1000001] = { 0 },ans = 0;//0是正图,1是反图
int n,m;struct rec{LL dis,x;friend bool operator < (rec a,rec b){return a.dis < b.dis || (a.dis==b.dis && a.x < b.x);}
};
multiset<rec>h;void dijkstra(int fx) //fx == 0 表示正方向 fx==1表示反方向。
{memset(dis[fx],255,sizeof dis[fx]);dis[fx][1] = 0;//初始化dis[0] == 0;h.clear();h.insert({0,1});while (!h.empty()){__typeof(h.begin()) c=h.begin();rec tou = (*c);h.erase(c);int x = tou.x;int len = g[fx][x].size();rep1(i,0,len-1){int y = g[fx][x][i];LL co = w[fx][x][i];if (dis[fx][y] == -1){dis[fx][y] = dis[fx][x] + co;h.insert({dis[fx][y],y});}elseif (dis[fx][y] > dis[fx][x] + co){c = h.upper_bound({dis[fx][y],y});c--;h.erase(c);dis[fx][y] = dis[fx][x]+co;h.insert({dis[fx][y],y});}}}
}int main()
{//freopen("F:\\rush.txt","r",stdin);scanf("%d%d", &n, &m);for (int i = 1; i <= m; i++)//用邻接表来存正图和反图{int x, y;LL z;rei(x);rei(y);rel(z);g[0][x].pb(y);w[0][x].pb(z);g[1][y].pb(x);w[1][y].pb(z);}dijkstra(0);//在正图和反图上做最短路dijkstra(1);for (int i = 2; i <= n; i++)//最后输出到达和返回的最短路的和即可。ans += (dis[0][i] + dis[1][i]);printf("%I64d\n", ans);return 0;
}

转载于:https://www.cnblogs.com/AWCXV/p/7626793.html

dijkstra堆优化(multiset实现-大大减小代码量)相关推荐

  1. A - Age of Moyu HDU - 6386(Dijkstra+堆优化)

    要解决这道题,可以用dfs+bfs,但是我不会,所以我只会dijkstra算法: 要解决这道题必须明白迪杰斯特拉算法的核心思想,我是这样理解的: 我可以任意举例一个图: 比如这个图,那么求1-6的最短 ...

  2. 寒假集训 最短路(I - Heavy Transportation)dijkstra+堆优化

    今天的集训学习了最短路dijkstra的堆优化,把时间复杂度从朴素版的O()降至了O(n*logn+m). 首先,先上一段朴素版的代码. void dijkstra() {dist[1] = 0;fo ...

  3. * Dijkstra 堆优化

    版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/Mashiro_ylb/article/ ...

  4. poj1511 InvitationCards 最短路 Dijkstra堆优化

    第一反应想到和 poj3268做法一样,先是从起点dj,然后将图反向,再次dj一次,求和即可.但是,数据O(n*n)过不去,所以需要使用dijkstra的堆优化! 淦,没用scanf结果超时了= = ...

  5. dijkstra+堆优化

    分析: 可知Dijkstra算法的复杂度是O(n*n) Dijkstra算法在寻找集合T中距离最小的顶点W(即寻找dist数组中最小值)复杂度是O(n),在更新距离操作时复杂度为O(n). 上述操作需 ...

  6. * poj 3159 Candies 最短路 dijkstra堆优化

    题意: n个人,m个信息,每行的信息是3个数字,A,B,C,表示B比A多出来的糖果不超过C个,问你,n号人最多比1号人多几个糖果 Input: 输入包含单个测试用例.测试用例以两个整数n和m开头,分别 ...

  7. HDU-6290 奢侈的旅行 2018女赛 Dijkstra堆优化

    又因为cost=log2∗((level+ai)/level)cost=log2*((level+a_i)/level)cost=log2∗((level+ai​)/level),cost会带着log ...

  8. HDU ACM 3986 Harry Potter and the Final Battle(邻接表实现最短路dijkstra堆优化记录路径 + 枚举最短路上每条边)...

    http://acm.hdu.edu.cn/showproblem.php?pid=3986 题意: 从起点1 到 终点n,删除图中任意一条边求最短路的最坏情况. n  --表示有n个点 m --边数 ...

  9. 牛客 刺客信条 (bfs、dijkstra)+堆优化、dfs三种求解

    最短路 BFS+优先队列 DFS dijkstra+堆优化 题目描述 万物皆虚,万事皆允,玩过刺客信条的人对这句话应该都不会感到陌生 小A也是非常痴迷于这款游戏,正巧最近<刺客信条·奥德赛> ...

最新文章

  1. java基础知识点_「Java面试题/知识点精华集」20000+字的Java基础知识篇(2020最新版) !
  2. 网易有道的产品总监王焱:如何利用数据分析推动产品设计
  3. 图解修改Windows启动菜单命令行工具BCDEdit
  4. 【解决方案】MTU现场能源发电机,点亮孤岛的文明之光
  5. windows下,怎么轻易拷贝一个文件的完整路径?
  6. mvcpager之学习
  7. 最全的http头部信息分析(转载)
  8. PyTorch | 保存和加载模型教程
  9. nonlocal python3_Python 中的 global、nonlocal 辨析
  10. auto.js停止所有线程_使用多线程处理输入的数据
  11. python实践项目(六)
  12. java实现栈的数据结构
  13. jenkins 下载插件 一直失败_实用测试技能分享:jmeter+Jenkins性能测试自动化搭建...
  14. C++之lock_guard和unique_lock自动加解锁区别
  15. Linux上修改open files数目
  16. LC3 正式升级 Open Source Summit,分论坛主题活动精彩纷呈
  17. ROS常用命令及脚本
  18. win10关机后cpu风扇还在转_win10电脑关机后风扇还在一直转怎么修复
  19. Vue-Cli 3.0 + vue.config.js
  20. CSS-Sprite(雪碧图)

热门文章

  1. dhtmlXTree 指南与实例(二)
  2. 2.4 线性相关和张成空间
  3. android字符串显示textview,Android编程:TextView不显示完整字符串
  4. pytorch —— Batch Normalization
  5. 自然语言处理 —— 困惑度
  6. Dirichlet Multinomial Mixture Model做短文本聚类
  7. 推荐系统——Item2vec
  8. IDEA远程部署调试Java应用程序
  9. 备战蓝桥杯—枚举——[USACO Nov08]成交
  10. 生产服务器怎么dmp堆栈信息,如何根据程序崩溃时的DMP文件使用WinDbg查找调用堆栈...