首页 > 代码库 > 分层图+最短路算法 BZOJ 2763: [JLOI2011]飞行路线
分层图+最短路算法 BZOJ 2763: [JLOI2011]飞行路线
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 1
0 4
0 1 5
1 2 5
2 3 5
3 4 5
2 3 3
0 2 100
0 4
0 1 5
1 2 5
2 3 5
3 4 5
2 3 3
0 2 100
Sample Output
8
HINT
对于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.
1 #include <queue> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #define N 11000 6 #define M 51000 7 #define inf 0x3f3f3f3f 8 using namespace std; 9 struct KSD10 {11 int v,len,next;12 }e[M<<1];13 int head[N],cnt;14 struct Lux15 {16 int x,y;17 Lux(int a,int b):x(a),y(b){}18 Lux(){}19 };20 void add(int u,int v,int len)21 {22 ++cnt;23 e[cnt].v=v;24 e[cnt].len=len;25 e[cnt].next=head[u];26 head[u]=cnt;27 }28 int n,m,p,s,t;29 int dist[11][N];30 bool in[11][N];/*spfa的dist,标记在每一层都要有*/31 queue<Lux>q;32 int spfa()33 {34 int i,v;35 memset(dist,0x3f,sizeof(dist));36 q.push(Lux(0,s));/*从第0层开始spfa*/37 dist[0][s]=0;38 in[0][s]=1;39 while(!q.empty())40 {41 Lux U=q.front();42 q.pop();43 in[U.x][U.y]=0;44 45 for(i=head[U.y];i;i=e[i].next)46 {47 v=e[i].v;/*先跑完这一层的最短路*/48 if(dist[U.x][v]>dist[U.x][U.y]+e[i].len)49 {50 dist[U.x][v]=dist[U.x][U.y]+e[i].len;51 if(!in[U.x][v])q.push(Lux(U.x,v)),in[U.x][v]=1;52 }53 }54 if(U.x<p)for(i=head[U.y];i;i=e[i].next)55 {/*如果还可以向下一层转移的话,就把这个点出发的每一条边都设为免费下一层转移,因为要记录每个点dist到底用了几个免费的路线,所以用二维数组--分层思想*/56 v=e[i].v;57 if(dist[U.x+1][v]>dist[U.x][U.y])58 {59 dist[U.x+1][v]=dist[U.x][U.y];60 if(!in[U.x+1][v])q.push(Lux(U.x+1,v)),in[U.x+1][v]=1;61 }62 }63 }64 65 int ret=inf;66 for(i=0;i<=p;i++)ret=min(ret,dist[i][t]);/*在每一层中都找到t的最小值(最多k条免费),为什么要在每一层都找,而不是只在最后一层寻找呢。假设有这么一种情况,由s--t的最少的路上的途径数目少于k条,那么在k之前的某一层上就有dis=0,但是如果必须使用k条路径的话,那么就会找的一条路途数多于k的路来满足这个条件,那么只用第k层的dis自然不是正确结果了。*/67 return ret;68 }69 70 int main()71 {72 // freopen("test.in","r",stdin);73 int i,j,k;74 int a,b,c;75 scanf("%d%d%d%d%d",&n,&m,&p,&s,&t);76 for(i=1;i<=m;i++)77 {78 scanf("%d%d%d",&a,&b,&c);79 add(a,b,c);/*无向图建立双向边*/80 add(b,a,c);81 }82 printf("%d\n",spfa());83 return 0;84 }
1 /*我的代码*/ 2 #define K 11 3 #include<iostream> 4 using namespace std; 5 #include<cstdio> 6 #include<queue> 7 #include<cstring> 8 #define N 10010 9 #define M 50010 10 struct QU{ 11 int ce,bh; 12 }; 13 struct Edge{ 14 int v,w,last; 15 }edge[M<<1]; 16 int head[N],dis[K][N],k,n,m,t=0,sta,en; 17 bool inque[K][N]; 18 inline int read() 19 { 20 int ff=1,ret=0; 21 char s=getchar(); 22 while(s<‘0‘||s>‘9‘) 23 { 24 if(s==‘-‘) ff=-1; 25 s=getchar(); 26 } 27 while(s>=‘0‘&&s<=‘9‘) 28 { 29 ret=ret*10+s-‘0‘; 30 s=getchar(); 31 } 32 return ret*ff; 33 } 34 void add_edge(int u,int v,int w) 35 { 36 ++t; 37 edge[t].v=v; 38 edge[t].w=w; 39 edge[t].last=head[u]; 40 head[u]=t; 41 } 42 void input() 43 { 44 n=read();m=read();k=read(); 45 sta=read();en=read(); 46 int a,b,c; 47 for(int i=1;i<=m;++i) 48 { 49 a=read();b=read();c=read(); 50 add_edge(a,b,c); 51 add_edge(b,a,c); 52 } 53 } 54 void SPFA() 55 { 56 memset(dis,100,sizeof(dis));/*注意赋值的最大值不要超界*/ 57 dis[0][sta]=0; 58 inque[0][sta]=true; 59 queue<QU>Q; 60 QU A; 61 A.ce=0; 62 A.bh=sta; 63 Q.push(A); 64 while(!Q.empty()) 65 { 66 QU NOw=Q.front(); 67 Q.pop(); 68 inque[NOw.ce][NOw.bh]=false; 69 for(int l=head[NOw.bh];l;l=edge[l].last) 70 { 71 if(dis[NOw.ce][edge[l].v]>edge[l].w+dis[NOw.ce][NOw.bh]) 72 { 73 dis[NOw.ce][edge[l].v]=edge[l].w+dis[NOw.ce][NOw.bh]; 74 if(!inque[NOw.ce][edge[l].v]) 75 { 76 inque[NOw.ce][edge[l].v]=true; 77 QU C; 78 C.bh=edge[l].v; 79 C.ce=NOw.ce; 80 Q.push(C); 81 } 82 } 83 } 84 if(NOw.ce==k) continue; 85 for(int l=head[NOw.bh];l;l=edge[l].last) 86 { 87 if(dis[NOw.ce+1][edge[l].v]>dis[NOw.ce][NOw.bh]) 88 { 89 dis[NOw.ce+1][edge[l].v]=dis[NOw.ce][NOw.bh]; 90 if(!inque[NOw.ce+1][edge[l].v]) 91 { 92 inque[NOw.ce+1][edge[l].v]=true; 93 QU C; 94 C.bh=edge[l].v; 95 C.ce=NOw.ce+1; 96 Q.push(C); 97 } 98 } 99 }100 }101 }102 int main()103 {104 input();105 SPFA();106 int ans=(1<<31)-1;107 for(int i=0;i<=k;++i)108 ans=min(ans,dis[i][en]);109 printf("%d\n",ans);110 return 0;111 }112
分层图+最短路算法 BZOJ 2763: [JLOI2011]飞行路线
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。