分层图
2017-03-17 08:29
176 查看
分层图 及堆优化dijkstra
遇到了据说个不太常用的思想叫分层图顺便补补课,写个堆优化的dijkstra
分层图主要是应用于 变化的最短路问题 问题常表现为一个最短路问题上加一些手脚,如减小一些边权,改变一些连接,但事先又不知道,或可以自由选择改变哪个边,最终求最短路等等。由于无法知道改变了那些边,所以用到分层图思想。
可以理解为 平行宇宙 一样的东西 就是把原图复制出来k个,然后在原图连接的基础上,在相邻层中间加一些要求的变化边,通常是单向的(保证从每一层到下一层不再回来),再跑最短路。
发个题吧
Illegal Motor (Motor.c/cpp/pas)
Description
在你的强力援助下,PCY 成功完成了之前的所有任务,他觉得,现在正是出去浪的大好时光。
于是,他来到高速公路上,找到一辆摩的前往几千公里以外他心仪的那家黄焖鸡米饭。
由于 PCY 的品味异于常人,途经几百个城市的黄焖鸡米饭他都不屑一顾,他只愿意前往他心中最
好的那家,但是为了一碗二十块钱的黄焖鸡米饭,他不愿意花上几千块的路费,他希望路费尽量
少。高速路上的警察叔叔被他的行为所打动,于是在多方协调下,最多 K 条城市之间的高速收费站
愿意免费为 PCY 放行(可以任意选择)。
显然,PCY 已经筋疲力尽,不想再动用自己的数学天才来计算他可以花费的最小路费,因此他希
望你可以帮他最后一次,他说他可以请你吃大碗的黄焖鸡米饭,还可以加一瓶豆奶。
现在给你 N 个城市(编号为 0 … N - 1),M 条道路,和每条高速公路的花费 Wi,以及题目所描
述的 K。 PCY 想从城市 S 到城市 T,因为他对 T 城市的黄焖鸡米饭情有独钟。
Input (Prefix.in)
第一行,三个整数 N,M,K,如题意所描述
第二行,两个整数 S,T,代表出发城市和目标城市编号
接下来 M 行,每行三个整数 X,Y,W,代表 X 和 Y 城市之间的高速公路收费为 W 元
Output (Prefix.out)
共一行,输出一个整数,代表 PCY 最少需要花费的路费。NOIP 模拟题
7
Sample Input
Sample Output
Explanation
自己动手,丰衣足食
Hint
对于 10%的数据,N <= 100,K = 0
对于 30%的数据,N <= 5,M <= 10,K <= 2
对于 100%的数据,N <= 10000,M <= 50000,K <= 10,Wi <= 10000
内存限制 256M,时间限制 1s
我们建个原图,再复制k层出来然后这样:
原图x到y有一条边权为13的边,然后再每两个相邻的层之间 从x到y’连个边权为0的边,y到x’亦如此,这样以后跑图时可以从x到y跑这个变,即不花钱,又因为它是单向的,所以跑不回去了,保证了不会死循环或出意外。最终比较每层图的dis【t】值,取最小的,即是通过了有些免费路的最小值。
因为任意选择免费路,所以不知道那条免费最好,所以分层来跑,即最后的最短路就是包含了一些边权为零的路,但不一定跑了那种组合,所以每层t点都应比较一下。
发个图(纯自己手画,有点丑)
像这样从x到y就可以走一条边权为0的边,然后再下一层中继续跑最短路,也有可能没走这个而走了另一条路,则两层的t就不一定哪个更近,所以比下。
分层图说完了,再来浅谈一下堆优化dijkstra。
优化的地方主要是在取出剩余点中dis最小的点时用了堆,直接取,而非循环一边。堆里存两个东西:一维是dis,并按这个维护的小根堆,然后二维是点的序号,取出来更新时也要用到。
好了,代码
#include<iostream> #include<cstdio> #include<cstring> #include<queue> #include<vector> #define inf 0x7f7f7f7f #define N 200050 #define M 4000010 using namespace std; int n,m,k,s,t; int dis ,ans,maxn,sum,nown; struct E{ int to,next,wi; }a[M];int last ,cnt; void bud(int u,int v,int w) { a[++cnt].to=v;a[cnt].wi=w; a[cnt].next=last[u];last[u]=cnt; } typedef pair<int,int>hp;//自定义类型,一维是dis值,二维是序号 void dijkstra()//堆优化dijkstra { priority_queue<hp,vector<hp>,greater<hp> >heap; memset(dis,inf,sizeof(dis)); dis[s]=0; heap.push(hp(0,s)); while(!heap.empty()){ hp now=heap.top();heap.pop(); int x=now.second; if(dis[x]<now.first)continue; for(int i=last[x];i;i=a[i].next){ if(dis[a[i].to]>dis[x]+a[i].wi){ dis[a[i].to]=dis[x]+a[i].wi; heap.push(hp(dis[a[i].to],a[i].to)); } } } } int main() { freopen("Motor.in","r",stdin); freopen("Motor.out","w",stdout); scanf("%d%d%d",&n,&m,&k); scanf("%d%d",&s,&t); for(int i=1;i<=m;++i){ int u,v,w; scanf("%d%d%d",&u,&v,&w); for(int j=0;j<=k;++j){//分层建图 bud(u+n*j,v+n*j,w); bud(v+n*j,u+n*j,w); if(j<k){ bud(u+n*j,v+n*(j+1),0); bud(v+n*j,u+n*(j+1),0); } } } ans=inf; dijkstra(); for(int i=0;i<=k;++i)ans=min(ans,dis[t+i*n]);//比较最优 printf("%d",ans); return 0; }
相关文章推荐
- bzoj1922: [Sdoi2010]大陆争霸 分层图最短路
- 【BZOJ3627】【JLOI2014】路径规划 分层图
- 【SGU438】The Glorious Karlutka River =) 分层图最大流
- poj 2763: [JLOI2011]飞行路线(spfa分层图最短路)
- 【BZOJ-3627】路径规划 分层图 + Dijkstra + spfa
- POJ 3662 Telephone Lines (分层图)
- [bfs树 分层图][DP] hihocoder Pro.1147 时空阵
- 分层图最短路问题详解
- [BZOJ2763][JLOI2011]飞行路线(分层图最短路)
- bzoj2763: [JLOI2011]飞行路线 分层图最短路
- 【最短路】【Heap-Dijkstra】【分层图】bzoj2662 [BeiJing wc2012]冻结
- 【codevs1912】汽车加油行驶问题 分层图最短路
- 伊吹萃香 纪中2556 分层图+spfa
- [网络流24题-14] 孤岛营救 - 分层图
- bzoj2763[JLOI2011]飞行路线 分层图最短路
- bzoj 1579: [Usaco2009 Feb]Revamping Trails 道路升级——分层图+dijkstra
- NOIP 2009 最优贸易 (强连通分量、缩点、拓扑排序、SPFA、分层图)
- 分层图【p4568】 [JLOI2011]飞行路线
- bzoj2662: [BeiJing wc2012]冻结 分层图最短路
- 汽车加油行驶问题(分层图最短路)