zoukankan      html  css  js  c++  java
  • bzoj2763 [JLOI2011]飞行路线

    Description

    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

    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.

    正解:分层图最短路。

    原来这就是所谓分层图最短路,还以为多么高级呢。。

    直接跑spfa即可,爆状态那么用循环队列,$TLE$那么交换枚举状态,先松弛不免费的,再松弛免费的。

     1 //It is made by wfj_2048~
     2 #include <algorithm>
     3 #include <iostream>
     4 #include <cstring>
     5 #include <cstdlib>
     6 #include <cstdio>
     7 #include <vector>
     8 #include <cmath>
     9 #include <queue>
    10 #include <stack>
    11 #include <map>
    12 #include <set>
    13 #define inf (1<<30)
    14 #define N (10010)
    15 #define il inline
    16 #define RG register
    17 #define ll long long
    18 #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
    19 
    20 using namespace std;
    21 
    22 struct edge{ int nt,to,dis; }g[20*N];
    23 struct data{ int x,k; }q[20*N];
    24 
    25 int head[N],dis[N][12],vis[N][12],S,T,n,m,k,num,size=200000;
    26 
    27 il int gi(){
    28     RG int x=0,q=1; RG char ch=getchar();
    29     while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
    30     if (ch=='-') q=-1,ch=getchar();
    31     while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar();
    32     return q*x;
    33 }
    34 
    35 il void insert(RG int from,RG int to,RG int dis){
    36     g[++num]=(edge){head[from],to,dis},head[from]=num; return;
    37 }
    38 
    39 il void spfa(){
    40     memset(dis,0x3f3f3f,sizeof(dis));
    41     RG int h=0,t=1; q[t]=(data){S,0},dis[S][0]=0,vis[S][0]=1;
    42     while (h!=t){
    43     ++h; if (h>size) h=1; RG data x=q[h]; RG int v;
    44     for (RG int i=head[x.x];i;i=g[i].nt){
    45         v=g[i].to;
    46         if (dis[v][x.k]>dis[x.x][x.k]+g[i].dis){
    47         dis[v][x.k]=dis[x.x][x.k]+g[i].dis;
    48         if (!vis[v][x.k]){
    49             ++t; if (t>size) t=1;
    50             q[t]=(data){v,x.k},vis[v][x.k]=1;
    51         }
    52         }
    53         if (x.k+1<=k && dis[v][x.k+1]>dis[x.x][x.k]){
    54         dis[v][x.k+1]=dis[x.x][x.k];
    55         if (!vis[v][x.k+1]){
    56             ++t; if (t>size) t=1;
    57             q[t]=(data){v,x.k+1},vis[v][x.k+1]=1;
    58         }
    59         }
    60     }
    61     vis[x.x][x.k]=0;
    62     }
    63     return;
    64 }
    65 
    66 il void work(){
    67     n=gi(),m=gi(),k=gi(),S=gi()+1,T=gi()+1;
    68     for (RG int i=1,u,v,w;i<=m;++i)
    69     u=gi()+1,v=gi()+1,w=gi(),insert(u,v,w),insert(v,u,w);
    70     spfa(),printf("%d
    ",dis[T][k]); return;
    71 }
    72 
    73 int main(){
    74     File("flight");
    75     work();
    76     return 0;
    77 }
  • 相关阅读:
    Linux GCC常用命令
    用两个栈实现一个队列(转载)
    BMP格式介绍(一)
    图像处理笔记(1): bmp文件结构处理与显示
    大数据竞赛平台——Kaggle 入门篇
    图像识别中的深度学习
    面向对象中的抽象和具体类的理解
    全排列算法
    少有程序员读的书
    照片回执
  • 原文地址:https://www.cnblogs.com/wfj2048/p/7197442.html
Copyright © 2011-2022 走看看