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

    传送门:>HERE<

    题意:给出一张无向图,可以选择跳过(权值改没0)条边,问从s到t的最短路

    解题思路

      这真是一道趣题。乍一看以为是求个最短路,然后减去最大的k条边。然而样例就是一个这种方法的反例——跳过一条原本很长的边也许可以省去好多条最短路内的边。这就让问题复杂化了

      想办法转化为会求解的普通单源最短路:分层图思想

      建立k张图,第i张图表示跳过了i条路径的。最后的答案就是每一层的图的d[t]的最小值。因此只要建好分层图,直接跑dijkstra就好了。如何建立呢?图与图之间每一层连得边权值为0. 那么只需要每一层都正常建,同时相邻的两张图交叉连一下权值为0的边就好了

    Code

      SPFA被卡,乖乖dijkstra吧

      另外,数组要开大(BZOJ是正常的报的是RE,luogu竟然莫名其妙报是TLE)

    /*by DennyQi*/
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <queue>
    #define  r  read()
    #define  Max(a,b)  (((a)>(b))?(a):(b))
    #define  Min(a,b)  (((a)<(b))?(a):(b))
    using namespace std;
    typedef long long ll;
    const int MAXN = 600010;
    const int MAXM = 2000010;
    const int INF = 0x3f3f3f3f;
    const int MOD = 998244353;
    inline int read(){
        int x = 0; int w = 1; register unsigned char c = getchar();
        for(; c^'-' && (c < '0' || c > '9'); c = getchar());
        if(c == '-') w = -1, c = getchar();
        for(; c >= '0' && c <= '9'; c = getchar()) x = (x<<3) + (x<<1) + c - '0';
        return x * w;
    }
    struct Node{
        int idx,w;
    };
    bool operator < (Node a, Node b){
        return a.w > b.w;
    }
    int N,M,K,s,t,x,y,z;
    int first[MAXM*2],next[MAXM*2],to[MAXM*2],cost[MAXM*2],num_edge;
    int d[MAXN],vis[MAXN];
    priority_queue <Node> q;
    inline void add(int u, int v, int w){
    //    printf("%d->%d (%d)
    ",u,v,w);
        to[++num_edge] = v;
        cost[num_edge] = w;
        next[num_edge] = first[u];
        first[u] = num_edge;
    }
    inline void Dijkstra(int s){
        memset(d, 0x3f, sizeof(d));
        int u,v;
        d[s] = 0;
        q.push((Node){s, 0});
        while(!q.empty()){
            u = q.top().idx; q.pop();
            if(vis[u]) continue;
    //        printf("u = %d
    ", u);
            vis[u] = 1;
            for(int i = first[u]; i; i = next[i]){
                v = to[i];
    //            printf("%d-> %d
    ",u,v);
                if(d[u] + cost[i] < d[v]){
                    d[v] = d[u] + cost[i];
                    q.push((Node){v, d[v]});
                }
            }
        }
    }
    int main(){
    //    freopen(".in", "r", stdin);
        N=r,M=r,K=r;
        s=r,t=r;
        for(int i = 1; i <= M; ++i){
            x=r,y=r,z=r;
            add(x,y,z);
            add(y,x,z);
            for(int k = 0; k < K; ++k){
                add(x + k * N, y + (k+1) * N, 0);
                add(y + k * N, x + (k+1) * N, 0);
                add(x + (k+1) * N, y + (k+1) * N, z);
                add(y + (k+1) * N, x + (k+1) * N, z);
            }
        }
        Dijkstra(s);
    /*    for(int i = 0; i <= N*(K+2); ++i){
            printf("d[%d] = %d
    ",i,d[i]);
        }*/
        int ans = INF;
        for(int k = 0; k <= K; ++k){
            ans = Min(ans, d[t + k * N]);
        }
        printf("%d", ans);
        return 0;
    }
  • 相关阅读:
    UIPasteboard 粘贴板
    UIViewController没有随着设备一起旋转的原因
    UIButton 应用选择状态(附:UIButton 常用状态)
    WebService 中参数为枚举时引发的血案
    设计模式(1)之面向对象设计原则 阿正
    2012年年终总结 阿正
    生活工作如登山 阿正
    感谢我的技术总监 阿正
    尽孝要尽早 阿正
    我老了吗?不 你依然年轻 阿正
  • 原文地址:https://www.cnblogs.com/qixingzhi/p/9390347.html
Copyright © 2011-2022 走看看