例题:



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});
}
else
if (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;
}

dijkstra堆优化(multiset实现->大大减小代码量)的更多相关文章

  1. hdu 2544 单源最短路问题 dijkstra+堆优化模板

    最短路 Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submis ...

  2. 深入理解dijkstra+堆优化

    深入理解dijkstra+堆优化 其实就这几种代码几种结构,记住了完全就可以举一反三,所以多记多练多优化多思考. Dijkstra   对于一个有向图或无向图,所有边权为正(边用邻接矩阵的形式给出), ...

  3. POJ 2502 - Subway Dijkstra堆优化试水

    做这道题的动机就是想练习一下堆的应用,顺便补一下好久没看的图论算法. Dijkstra算法概述 //从0出发的单源最短路 dis[][] = {INF} ReadMap(dis); for i = 0 ...

  4. Bzoj 2834: 回家的路 dijkstra,堆优化,分层图,最短路

    2834: 回家的路 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 62  Solved: 38[Submit][Status][Discuss] D ...

  5. POJ2387(dijkstra堆优化)

    Til the Cows Come Home Bessie is out in the field and wants to get back to the barn to get as much s ...

  6. 【Dijkstra堆优化】洛谷P2243电路维修

    题目背景 Elf 是来自Gliese 星球的少女,由于偶然的原因漂流到了地球上.在她无依无靠的时候,善良的运输队员Mark 和James 收留了她.Elf 很感谢Mark和James,可是一直也没能给 ...

  7. hdu3790 dijkstra+堆优化

    题目来源:http://acm.hdu.edu.cn/showproblem.php?pid=3790 分析:dijkstra没有优化的话,复杂度是n*n,优化后的复杂度是m*logm,n是顶点数,m ...

  8. POJ-2387.Til the Cows Come Home.(五种方法:Dijkstra + Dijkstra堆优化 + Bellman-Ford + SPFA + Floyd-Warshall)

    昨天刚学习完最短路的算法,今天开始练题发现我是真的菜呀,居然能忘记邻接表是怎么写的,真的是菜的真实...... 为了弥补自己的菜,我决定这道题我就要用五种办法写出,并在Dijkstra算法堆优化中另外 ...

  9. 洛谷P3371单源最短路径Dijkstra堆优化版及优先队列杂谈

    其实堆优化版极其的简单,只要知道之前的Dijkstra怎么做,那么堆优化版就完全没有问题了. 在做之前,我们要先学会优先队列,来完成堆的任务,下面盘点了几种堆的表示方式. priority_queue ...

随机推荐

  1. day39-Spring 02-AOP的概述

     横向抽取的机制其实就是代理机制.对UserDao生成一个代理类:UserDaoProxy.被代理对象和代理对象它俩实现相同的接口它俩肯定是平级的,这就是横向抽取的机制.如果这时候调用UserDao的 ...

  2. day39 10-Spring的AOP:基于AspectJ的切点定义

    切点是我们真正应用在哪些方法上,增强的那些方法上,就是add().update()和find().delete()是没用的.没用的话就是这三个方法.为什么要定义一个切点呢? 所以可以直接在切面中定义一 ...

  3. 为什么printf()用%f输出double型,而scanf却用%lf呢?

    之前没有注意过这个问题,  转自: http://book.51cto.com/art/200901/106880.htm 问:有人告诉我不能在printf中使用%lf.为什么printf()用%f输 ...

  4. Oracle日期

    oracle 日期格式 to_date("要转换的字符串","转换的格式")   两个参数的格式必须匹配,否则会报错. 即按照第二个参数的格式解释第一个参数. ...

  5. 撸了一个微信小程序项目

    学会一项开发技能最快的步骤就是:准备,开火,瞄准.最慢的就是:准备,瞄准,瞄准,瞄准-- 因为微信小程序比较简单,直接开撸就行,千万别瞄准. 于是乎,趁着今天上午空气质量不错,撸了一个小程序,放在了男 ...

  6. easyUI + servlet 展示datagrid数据列表

    1:在jsp页面添加所用easyUI的js和css 2.前台代码示例: <table id="dgObj" style="width: 100%;height:90 ...

  7. jQuery show hide方法 二级菜单

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. Spring Data JPA 查询结果返回至自定义实体

    本人在实际工作中使用Spring Data Jpa框架时,一般查询结果只返回对应的Entity实体.但有时根据实际业务,需要进行一些较复杂的查询,比较棘手.虽然在框架上我们可以使用@Query注解执行 ...

  9. @codeforces - 1209G2@ Into Blocks (hard version)

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 定义一个序列是好的,当且仅当这个序列中,相等的两个数之间的所有数 ...

  10. 2019-8-31-dotnet-通过-WMI-获取系统补丁

    title author date CreateTime categories dotnet 通过 WMI 获取系统补丁 lindexi 2019-08-31 16:55:59 +0800 2019- ...