分层图+最短路算法 BZOJ 2763: [JLOI2011]飞行路线
2016-10-02 12:26
302 查看
2763: [JLOI2011]飞行路线
Time Limit: 10 Sec Memory Limit: 128 MBDescription
Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司。该航空公司一共在n个城市设有业务,设这些城市分别标记为0到n-1,一共有m种航线,每种航线连接两个城市,并且航线有一定的价格。Alice和Bob现在要从一个城市沿着航线到达另一个城市,途中可以进行转机。航空公司对他们这次旅行也推出优惠,他们可以免费在最多k种航线上搭乘飞机。那么Alice和Bob这次出行最少花费多少?Input
数据的第一行有三个整数,n,m,k,分别表示城市数,航线数和免费乘坐次数。第二行有两个整数,s,t,分别表示他们出行的起点城市编号和终点城市编号。(0<=s,t<n)
接下来有m行,每行三个整数,a,b,c,表示存在一种航线,能从城市a到达城市b,或从城市b到达城市a,价格为c。(0<=a,b<n,a与b不相等,0<=c<=1000)
Output
只有一行,包含一个整数,为最少花费。Sample Input
5 6 10 4
0 1 5
1 2 5
2 3 5
3 4 5
2 3 3
0 2 100
Sample Output
8HINT
对于30%的数据,2<=n<=50,1<=m<=300,k=0;对于50%的数据,2<=n<=600,1<=m<=6000,0<=k<=1;
对于100%的数据,2<=n<=10000,1<=m<=50000,0<=k<=10.
#include <queue> #include <cstdio> #include <cstring> #include <algorithm> #define N 11000 #define M 51000 #define inf 0x3f3f3f3f using namespace std; struct KSD { int v,len,next; }e[M<<1]; int head ,cnt; struct Lux { int x,y; Lux(int a,int b):x(a),y(b){} Lux(){} }; void add(int u,int v,int len) { ++cnt; e[cnt].v=v; e[cnt].len=len; e[cnt].next=head[u]; head[u]=cnt; } int n,m,p,s,t; int dist[11] ; bool in[11] ;/*spfa的dist,标记在每一层都要有*/ queue<Lux>q; int spfa() { int i,v; memset(dist,0x3f,sizeof(dist)); q.push(Lux(0,s));/*从第0层开始spfa*/ dist[0][s]=0; in[0][s]=1; while(!q.empty()) { Lux U=q.front(); q.pop(); in[U.x][U.y]=0; for(i=head[U.y];i;i=e[i].next) { v=e[i].v;/*先跑完这一层的最短路*/ if(dist[U.x][v]>dist[U.x][U.y]+e[i].len) { dist[U.x][v]=dist[U.x][U.y]+e[i].len; if(!in[U.x][v])q.push(Lux(U.x,v)),in[U.x][v]=1; } } if(U.x<p)for(i=head[U.y];i;i=e[i].next) {/*如果还可以向下一层转移的话,就把这个点出发的每一条边都设为免费下一层转移,因为要记录每个点dist到底用了几个免费的路线,所以用二维数组--分层思想*/ v=e[i].v; if(dist[U.x+1][v]>dist[U.x][U.y]) { dist[U.x+1][v]=dist[U.x][U.y]; if(!in[U.x+1][v])q.push(Lux(U.x+1,v)),in[U.x+1][v]=1; } } } int ret=inf; for(i=0;i<=p;i++)ret=min(ret,dist[i][t]);/*在每一层中都找到t的最小值(最多k条免费),为什么要在每一层都找,而不是只在最后一层寻找呢。假设有这么一种情况,由s--t的最少的路上的途径数目少于k条,那么在k之前的某一层上就有dis=0,但是如果必须使用k条路径的话,那么就会找的一条路途数多于k的路来满足这个条件,那么只用第k层的dis自然不是正确结果了。*/ return ret; } int main() { // freopen("test.in","r",stdin); int i,j,k; int a,b,c; scanf("%d%d%d%d%d",&n,&m,&p,&s,&t); for(i=1;i<=m;i++) { scanf("%d%d%d",&a,&b,&c); add(a,b,c);/*无向图建立双向边*/ add(b,a,c); } printf("%d\n",spfa()); return 0; }
/*我的代码*/ #define K 11 #include<iostream> using namespace std; #include<cstdio> #include<queue> #include<cstring> #define N 10010 #define M 50010 struct QU{ int ce,bh; }; struct Edge{ int v,w,last; }edge[M<<1]; int head ,dis[K] ,k,n,m,t=0,sta,en; bool inque[K] ; inline int read() { int ff=1,ret=0; char s=getchar(); while(s<'0'||s>'9') { if(s=='-') ff=-1; s=getchar(); } while(s>='0'&&s<='9') { ret=ret*10+s-'0'; s=getchar(); } return ret*ff; } void add_edge(int u,int v,int w) { ++t; edge[t].v=v; edge[t].w=w; edge[t].last=head[u]; head[u]=t; } void input() { n=read();m=read();k=read(); sta=read();en=read(); int a,b,c; for(int i=1;i<=m;++i) { a=read();b=read();c=read(); add_edge(a,b,c); add_edge(b,a,c); } } void SPFA() { memset(dis,100,sizeof(dis));/*注意赋值的最大值不要超界*/ dis[0][sta]=0; inque[0][sta]=true; queue<QU>Q; QU A; A.ce=0; A.bh=sta; Q.push(A); while(!Q.empty()) { QU NOw=Q.front(); Q.pop(); inque[NOw.ce][NOw.bh]=false; for(int l=head[NOw.bh];l;l=edge[l].last) { if(dis[NOw.ce][edge[l].v]>edge[l].w+dis[NOw.ce][NOw.bh]) { dis[NOw.ce][edge[l].v]=edge[l].w+dis[NOw.ce][NOw.bh]; if(!inque[NOw.ce][edge[l].v]) { inque[NOw.ce][edge[l].v]=true; QU C; C.bh=edge[l].v; C.ce=NOw.ce; Q.push(C); } } } if(NOw.ce==k) continue; for(int l=head[NOw.bh];l;l=edge[l].last) { if(dis[NOw.ce+1][edge[l].v]>dis[NOw.ce][NOw.bh]) { dis[NOw.ce+1][edge[l].v]=dis[NOw.ce][NOw.bh]; if(!inque[NOw.ce+1][edge[l].v]) { inque[NOw.ce+1][edge[l].v]=true; QU C; C.bh=edge[l].v; C.ce=NOw.ce+1; Q.push(C); } } } } } int main() { input(); SPFA(); int ans=(1<<31)-1; for(int i=0;i<=k;++i) ans=min(ans,dis[i][en]); printf("%d\n",ans); return 0; }
相关文章推荐
- Bzoj 2763: [JLOI2011]飞行路线 dijkstra,堆,最短路,分层图
- bzoj 2763: [JLOI2011]飞行路线【分层图+spfa】
- BZOJ 2763 JLOI2011 飞行路线 分层图+堆优化SPFA
- 【bzoj2763】[JLOI2011]飞行路线 分层图最短路
- bzoj2763[JLOI2011]飞行路线 分层图最短路
- Bzoj 2763: [JLOI2011]飞行路线 拆点,分层图,最短路,SPFA
- [BZOJ2763][JLOI2011]飞行路线(分层图最短路)
- BZOJ2763 [JLOI2011]飞行路线 【分层图 + 最短路】
- BZOJ2763 [JLOI2011]飞行路线 【分层图 + 最短路】
- [bzoj2763]2763: [JLOI2011]飞行路线 分层图最短路
- [BZOJ2763][JLOI2011][分层图最短路]飞行路线
- bzoj 2763: [JLOI2011]飞行路线 分层图最短路
- BZOJ 2763 JLOI 2011 飞行路线 分层图+最短路
- bzoj 2763: [JLOI2011]飞行路线 分层图
- BZOJ 2763: [JLOI2011]飞行路线 分层图最短路
- bzoj 2763 JLOI 2011 飞行路线 分层图+spfa
- 分层图,bzoj2763: [JLOI2011]飞行路线
- 【JLOI2011】【bzoj2763】飞行路线 分层图最短路
- bzoj 2763: [JLOI2011]飞行路线 -- 分层图最短路
- BZOJ 2763: [JLOI2011]飞行路线(分层图最短路)