zoukankan      html  css  js  c++  java
  • BZOJ2763 [JLOI2011]飞行路线 【分层图 + 最短路】

    题目

    Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司。该航空公司一共在n个城市设有业务,设这些城市分别标记为0到n-1,一共有m种航线,每种航线连接两个城市,并且航线有一定的价格。Alice和Bob现在要从一个城市沿着航线到达另一个城市,途中可以进行转机。航空公司对他们这次旅行也推出优惠,他们可以免费在最多k种航线上搭乘飞机。那么Alice和Bob这次出行最少花费多少?

    输入格式

    数据的第一行有三个整数,n,m,k,分别表示城市数,航线数和免费乘坐次数。
    第二行有两个整数,s,t,分别表示他们出行的起点城市编号和终点城市编号。(0<=s,t

    输出格式

    只有一行,包含一个整数,为最少花费。

    输入样例

    5 6 1

    0 4

    0 1 5

    1 2 5

    2 3 5

    3 4 5

    2 3 3

    0 2 100

    输出样例

    8

    提示

    对于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.

    题解

    就是一个分层图,按剩余免费次数分10层,每次转移可以考虑使用和不使用免费次数,跑一遍SPFA即可【8s险过

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<algorithm>
    #define LL long long int
    #define REP(i,n) for (int i = 1; i <= (n); i++)
    #define Redge(u) for (int k = h[u]; k != -1; k = ed[k].nxt)
    using namespace std;
    const int maxn = 10005,maxm = 100005,INF = 1000000000;
    inline int RD(){
        int out = 0,flag = 1; char c = getchar();
        while (c < 48 || c > 57) {if (c == '-') flag = -1; c = getchar();}
        while (c >= 48 && c <= 57) {out = (out << 1) + (out << 3) + c - '0'; c = getchar();}
        return out * flag;
    }
    int h[maxn],ne = 0,N,M,K,S,T,d[11][maxn],inq[11][maxn];
    struct EDGE{int to,nxt,w;}ed[maxm];
    inline void build(int u,int v,int w){
        ed[ne] = (EDGE){v,h[u],w}; h[u] = ne++;
        ed[ne] = (EDGE){u,h[v],w}; h[v] = ne++;
    }
    struct node{int k,u;};
    queue<node> q;
    void SPFA(){
        fill(d[0],d[0] + 11 * maxn,INF);
        node u; int to;
        q.push((node){K,S}); d[K][S] = 0;
        while (!q.empty()){
            u = q.front(); q.pop();
            inq[u.k][u.u] = false;
            Redge(u.u){
                to = ed[k].to;
                if (d[u.k][to] > d[u.k][u.u] + ed[k].w){
                    d[u.k][to] = d[u.k][u.u] + ed[k].w;
                    if (!inq[u.k][to]) q.push((node){u.k,to}),inq[u.k][to] = true;
                }
                if (u.k && d[u.k - 1][to] > d[u.k][u.u]){
                    d[u.k - 1][to] = d[u.k][u.u];
                    if (!inq[u.k - 1][to]) q.push((node){u.k - 1,to}),inq[u.k - 1][to] = true;
                }
            }   
        }
        int ans = INF;
        for (int i = 0; i <= K; i++) ans = min(ans,d[i][T]);
        printf("%d",ans);
    }
    int main(){
        memset(h,-1,sizeof(h));
        N = RD(); M = RD(); K = RD(); S = RD() + 1; T = RD() + 1; int a,b,w;
        while (M--) a = RD() + 1,b = RD() + 1,w = RD(),build(a,b,w);
        SPFA();
        return 0;
    }
    
  • 相关阅读:
    js在html中的加载执行顺序
    外部JS的阻塞下载
    mysql 中文字段排序
    PHP 多维数组排序 array_multisort()
    最简单的Linux下apache+mysql+php安装
    [TJOI2008] 彩灯 (线性基)
    [洛谷P2257] YY的GCD (莫比乌斯反演)
    [SDOI2015] 约数个数和 (莫比乌斯反演)
    [POI2007] ZAP-Queries (莫比乌斯反演)
    [NOI2003] 文本编辑器 (splay)
  • 原文地址:https://www.cnblogs.com/Mychael/p/8282726.html
Copyright © 2011-2022 走看看