zoukankan      html  css  js  c++  java
  • 第K短路径 POJ 2449

    第K短路径 POJ 2449

    一个朴实的算法是搜索出所有的路径,去第k短。

    然后我们尝试能否让第一次到底的最短路径,第二次到达的第二短。其实是给A*。
    我们维护已经走了多远和距离终点还有多远的距离和小的优先走,就能达到上述要求。
    距离终点还有多远反向建图,求一次最短路即可。

    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <queue>
    
    using namespace std;
    const int MAXN = 1050;
    const int MAXM = 1e5 + 10;
    
    int n, m, first[MAXN], sign;
    
    int dist[MAXN], S, T, K;
    
    struct Edge {
        int to, w, next;
    } edge[MAXM * 4];
    
    void init() {
        memset(first, -1, sizeof(first));
        sign = 0;
    }
    
    void add_edge(int u, int v, int w) {
        edge[sign].to = v;
        edge[sign].w = w;
        edge[sign].next = first[u];
        first[u] = sign++;
    }
    
    struct Input {
        int u, v, w;
    } in[MAXM];
    
    struct PriNode {
        int to, cost;
        PriNode(int tt = 0, int cc = 0):to(tt), cost(cc) {}
        friend bool operator < (const PriNode &a, const PriNode &b) {
            return a.cost > b.cost;
        }
    };
    
    void dijkstra(int s) {
        priority_queue<PriNode>que;
        que.push(PriNode(s, 0));
        memset(dist, -1, sizeof(dist));
        while(!que.empty()) {
            PriNode now = que.top();
            que.pop();
            if(dist[now.to] == -1) {
                dist[now.to] = now.cost;
                for(int i = first[now.to]; ~i; i = edge[i].next) {
                    int to = edge[i].to, w = edge[i].w;
                    if(dist[to] == -1) {
                        que.push(PriNode(to, now.cost + w));
                    }
                }
            }
        }
    }
    
    struct Node {
        int to, val;
        Node(int tt = 0, int vv = 0):to(tt), val(vv) {}
        friend bool operator < (const Node &a, const Node &b) {
            return a.val + dist[a.to] > b.val + dist[b.to];
        }
    };
    
    int a_start(int S, int T, int K) {
        priority_queue<Node>que;
        que.push(Node(S, 0));
        while(!que.empty()) {
            Node now = que.top();
            que.pop();
            if(now.to == T) {
                if(K > 1) {
                    K--;
                } else {
                    return now.val;
                }
            }
            for(int i = first[now.to]; ~i; i = edge[i].next) {
                int to = edge[i].to, w = edge[i].w;
                que.push(Node(edge[i].to, now.val + w));
            }
        }
        return -1;
    }
    
    int main() {
        init();
        scanf("%d %d", &n, &m);
        for(int i = 1; i <= m; i++ ) {
            scanf("%d %d %d", &in[i].u, &in[i].v, &in[i].w);
            add_edge(in[i].v, in[i].u, in[i].w);
        }
        scanf("%d %d %d", &S, &T, &K);
        dijkstra(T);
        if(dist[S] == -1) {
            puts("-1");
            return 0;
        }
        if(S == T) {
            K++;
        }
        init();
        for(int i = 1; i <= m; i++ ) {
            add_edge(in[i].u, in[i].v, in[i].w);
        }
        printf("%d
    ", a_start(S, T, K));
        return 0;
    }
    
  • 相关阅读:
    第 02 组 每周小结 (2/3)
    第02组 每周小结(1/3)
    第02组 beta冲刺总结
    第02组 beta冲刺(5/5)
    第02组 beta冲刺(4/5)
    第02组 beta冲刺(3/5)
    第02组 beta冲刺(2/5)
    第02组beta冲刺(1)
    将博客搬至CSDN
    制作鼠标放在图片上,一闪而过水波的效果
  • 原文地址:https://www.cnblogs.com/Q1143316492/p/9623456.html
Copyright © 2011-2022 走看看