【UVA11374】Airport Express
来源:互联网 发布:dom编程艺术第二版txt 编辑:程序博客网 时间:2024/05/02 01:37
题意
Graph= {V,E1,E2 },边有边权
现在要从S 到达T ,期间有一次机会能够通过E2 中的边,其余时候只能走E1 中的边,问最短路径,最短路,如果使用了E2 中的边,还需输出经过边的起点
|V|≤500,|E1|≤1000,|E2|≤1000
解法
分层图最短路:
一般来说,这道题的做法都是枚举通过哪一条边,这种做法可以通过本题,但是对于更大规模的数据来说,例如能够使用多次机会或者|V|更大 ,那就无法解决了,此时就需要使用分层图最短路
分层图最短路是指在可以进行分层图的图上解决最短路问题,一般模型是:
在图上,有k 次机会可以0代价通过一条边或者经过另外一个边集之中的边,问起点与终点之间的最短路径
解决这类问题的关键就是怎么建立分层图。一般来说,有以下原则:
①.同一层之间的边直接按输入连接
②.有向边直接从本层的起点连向下一层的终点,无向图的话就从本层起点连向下层终点,从本层终点连向下层起点
然后从第一层的起点出发,进行最短路求解,最后的答案就是每一层的终点的最短路径的最小值
另外,一般来说,分层图问题的边会比较多,使用spfa 效率不高(k∗nm ),所以一般使用堆优化的Dijkstra ,可以在nlogn 的时间内解决
复杂度
O(T*2*n*log(2*n))
代码
#include<iostream>#include<cstdlib>#include<cstring>#include<cstdio>#define ls 2*k#define rs 2*k+1#define Rint register int#define Lint long long intusing namespace std;const int INF=0x3f3f3f3f;const int E=50010;const int N=5010;struct Edge{ int next; int u,v,w;}t[E];struct Head{ int a[N*10],dis[N*10]; int tail; void Swap(int x,int y) { swap( a[x],a[y] ); swap( dis[x],dis[y] ); } void insert(Rint k,Rint w) { a[++tail]=k,dis[tail]=w; int tmp=tail; while( tmp>=2 ) { if( dis[tmp]<dis[tmp/2] ) { Swap( tmp,tmp/2 ); tmp=tmp/2; } else break ; } } void update(Rint k) { int tmp=k; if( ls<=tail && dis[ls]<dis[tmp] ) tmp=ls; if( rs<=tail && dis[rs]<dis[tmp] ) tmp=rs; if( tmp!=k ) { Swap( tmp,k ); update( tmp ); } } void pop() { Swap( 1,tail ),tail--; update( 1 ); } int top() { return a[1]; } bool empty() { return !tail; }}q;int head[N],num;int dis[N],vis[N];int Pre[N],s[N];int n,m,k,S,T;int cnt;void add(int u,int v,int w){ t[++num]=(Edge){ head[u],u,v,w }; head[u]=num;}void work(){ int tmp; for(int i=1;i<=2*n;i++) dis[i]=INF,vis[i]=0; dis[S]=0,q.insert( S,0 ); while( !q.empty() ) { tmp=q.top(),q.pop(); if( vis[tmp] ) continue ; vis[tmp]=1; for(int i=head[tmp],x; i ;i=t[i].next) { x=t[i].v; if( dis[x]>dis[tmp]+t[i].w && !vis[x] ) { Pre[x]=i; dis[x]=dis[tmp]+t[i].w; q.insert( x,dis[x] ); } } }}int main(){ int u,v,w,C=0; while( scanf("%d%d%d",&n,&S,&T)!=EOF ) { if( ++C>1 ) printf("\n"); cnt=num=0; memset( Pre,0x0,sizeof Pre ); memset( head,0x0,sizeof head ); scanf("%d",&m); for(int i=1;i<=m;i++) { scanf("%d%d%d",&u,&v,&w); add( u,v,w ),add( v,u,w ); add( u+n,v+n,w ),add( v+n,u+n,w ); } scanf("%d",&k); for(int i=1;i<=k;i++) { scanf("%d%d%d",&u,&v,&w); add( u,v+n,w ),add( v,u+n,w ); } work(); if( dis[T]<dis[T+n] ) { u=0,v=dis[T],s[++cnt]=T; for(int i=Pre[T]; i ;i=Pre[t[i].u]) { s[++cnt]= t[i].u>n ? t[i].u-n : t[i].u ; if( t[i].v>n ) u=t[i].u; } } else { u=0,v=dis[T+n],s[++cnt]=T; for(int i=Pre[T+n]; i ;i=Pre[t[i].u]) { s[++cnt]= t[i].u>n ? t[i].u-n : t[i].u ; if( t[i].v>n ) u=t[i].u; } } printf("%d",s[cnt]); for(int i=cnt-1;i>=1;i--) printf(" %d",s[i]); printf("\n"); if( u ) printf("%d\n",u); else printf("Ticket Not Used\n"); printf("%d\n",v); } return 0;}
阅读全文
1 0
- uva11374 Airport Express
- UVa11374 Airport Express
- 【UVA11374】Airport Express
- uva11374 - Airport Express 最短路
- uva11374 Airport Express(最短路+枚举)
- UVA11374 Airport Express(SPFA求最短路)
- UVA11374-Airport Express(最短路+枚举)
- UVA11374[Airport Express] dijkstra/spfa+枚举
- Airport Express
- Airport Express
- UVA 11374 - Airport Express
- UVA 11374 Airport Express
- Uva-11374-Airport Express
- UVA 11374 Airport Express
- UVa 11374 Airport Express
- uva 11374/Airport Express
- UVa 11374 - Airport Express
- Uva11374
- 5、上卷下拉效果--动画篇
- LL(1)文法
- github----向开源框架提交pr的过程
- Codeforces Round #441 (Div. 1, by Moscow Team Olympiad) F. Royal Questions
- angular4中动画及路由动画的使用
- 【UVA11374】Airport Express
- skynet 学习笔记
- Android Study Material Design 四 之:DrawerLayout+NavigationView组合实现侧滑 ^_^
- 2017上海易保云笔试题
- 直角三角形的判定
- cell,fix,floor,round
- 搬家声明
- 字串距离(字符串dp)
- 项目中的删除功能