zoukankan      html  css  js  c++  java
  • 【BZOJ2763/洛谷p4563】【分层图最短路】飞行路线

    2763: [JLOI2011]飞行路线

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 4630  Solved: 1797
    [Submit][Status][Discuss]

    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.


    Source

     
    [Submit][Status][Discuss]


    HOME Back

    洛谷上面的数据卡常毒瘤啊!!巴中随手a,洛谷交了快10次...加了一些玄学优化...

    spfa里面如果当前状态的cost已经大于等于到终点时的相同状态的cost,就不把这个状态加入队列了。然后就是RG大法好!!

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #define RG register
    using namespace std;
    
    int n, k, m, s, t;
    int dp[10005][15];
    
    struct node {
        int u, k;
        node ( int u, int k ) :
            u ( u ), k ( k ) {    }
    };
    
    int stot, nex[100005], h[10005], tov[100005], w[100005];
    void add ( int u, int v, int ss ) {
        tov[++stot] = v;
        w[stot] = ss;
        nex[stot] = h[u];
        h[u] = stot;
    }
    
    int vis[10005][15];
    queue < node > q;
    
    void spfa ( ) {
        memset ( dp, 0x3f3f3f3f, sizeof ( dp ) );
        vis[s][0] = 1;
        dp[s][0] = 0;
        q.push ( node ( s, 0 ) );
        while ( !q.empty ( ) ) {
            node x = q.front ( ); q.pop ( ); vis[x.u][x.k] = 0;
            for ( RG int i = h[x.u]; i; i = nex[i] ) {
                int v = tov[i];
                if ( dp[v][x.k] > dp[x.u][x.k] + w[i] ) {
                    dp[v][x.k] = dp[x.u][x.k] + w[i];
                    if ( !vis[v][x.k] && dp[v][x.k] <= dp[t][x.k] ) {
                        vis[v][x.k] = 1;
                        q.push ( node ( v, x.k ) );
                    }
                }
                if ( x.k < k && dp[v][x.k+1] > dp[x.u][x.k] ) {
                    dp[v][x.k+1] = dp[x.u][x.k];
                    if ( !vis[v][x.k+1] && dp[v][x.k+1] <= dp[t][x.k+1] ) {
                        vis[v][x.k+1] = 1;
                        q.push ( node ( v, x.k + 1 ) );
                    }
                }
            }    
        }
    }
    
    int main ( ) {
        scanf ( "%d%d%d", &n, &m, &k );
        scanf ( "%d%d", &s, &t );
        for ( RG int i = 1; i <= m; i ++ ) {
            int u, v, s;
            scanf ( "%d%d%d", &u, &v, &s );
            add ( u, v, s );
            add ( v, u, s );
        }
        spfa ( );
        printf ( "%d", dp[t][k] );
        return 0;
    }
  • 相关阅读:
    判断图片是否存在,不存在则显示默认图片
    移动端开发时代理手机http访问查看效果(iphone)
    VS Code搭建TypeScript开发环境
    map,foreach和for的使用
    记一些常用的git命令
    js中创建对象的5种方法
    vuex简单使用
    记一下Slot的使用
    ES6中的箭头函数和普通函数有什么区别?
    计算属性、方法、侦听属性的区别
  • 原文地址:https://www.cnblogs.com/wans-caesar-02111007/p/9478194.html
Copyright © 2011-2022 走看看