zoukankan      html  css  js  c++  java
  • ZOJ 3223 Journey to the Center of the Earth

    二维的最短路。

    题意:无向图,节点之间除了边外有“快捷方式”,快捷方式可以看作特殊的边,从起点到终点,给定时限,求使用快捷方式的最少次数。

    dist[i][j] :到达第i个点,且经过了j个快捷路径的最短时间。

    优先队列的最短路优化。

    1。如果已经走到终点还是要继续扩展,因为可能出现使用快捷方式更少的方案

    2。如果已经到终点,可以用当前这个快捷方式数作为限制,继续扩展的节点的使用快捷方式数要小于这个值。

    3。如果以前经过这个节点,这次再经过时快捷方式数必须更少,才有必要扩展。

    4。如果超过时限的节点不扩展。



    #include <cstdio>
    #include <cstring>
    #include <vector>
    #include <algorithm>
    #include <queue>
    using namespace std;
    #define N 102
    #define E 10020
    #define inf 0x3f3f3f3f
    struct node {
        int u, l, s;
        node (int a=0, int b=0, int c=0): u(a), l(b), s(c) {}
        bool operator < (const node &a) const {
            return l > a.l;
        }
    };
    struct Node {
        int u, l;
        Node(int a=0, int b=0): u(a), l(b) {}
    };
    vector<Node> g[N], sg[N];
    int n, m, S, in, out, t;
    bool inq[N][E];
    int dist[N][E];
    
    int spfa() {
        priority_queue<node> Q;
        int limit = S;
        node x, y;
    
        memset(inq, false, sizeof(inq));
        for (int i=1; i<=n; i++)
            for (int j=0; j<=S; j++) dist[i][j] = inf;
    
    
        Q.push(node(in, 0, 0));
        dist[in][0] = 0;
    
        while (!Q.empty()) {
            x = Q.top(); Q.pop();
            if (x.u == out && x.s < limit) limit = x.s;
            if (!inq[x.u][x.s]) {
                for (size_t i=0; i<g[x.u].size(); i++) {
                    y.u = g[x.u][i].u;
                    y.l = x.l + g[x.u][i].l;
                    y.s = x.s;
                    if (y.l < dist[y.u][y.s] && y.l <= t) {
                        dist[y.u][y.s] = y.l;
                        Q.push(y);
                    }
                }
                if (x.s < limit) {
                    for (size_t i=0; i<sg[x.u].size(); i++) {
                        y.u = sg[x.u][i].u;
                        y.l = x.l + sg[x.u][i].l;
                        y.s = x.s + 1;
                        if (y.l < dist[y.u][y.s] && y.l <= t) {
                            dist[y.u][y.s] = y.l;
                            Q.push(y);
                        }
                    }
                }
            }
            inq[x.u][x.s] = true;
        }
        for (int i=0; i<=S; i++)
            if (dist[out][i] <= t) return i;
        return -1;
    }
    int main() {
        while (scanf("%d%d", &n, &m) == 2) {
            int u, v, l;
            for (int i=0; i<=n; i++) { g[i].clear(); sg[i].clear(); }
            for (int i=0; i<m; i++) {
                scanf("%d%d%d", &u, &v, &l);
                g[u].push_back(Node(v, l));
                g[v].push_back(Node(u, l));
            }
            scanf("%d", &S);
            for (int i=0; i<S; i++) {
                scanf("%d%d%d", &u, &v, &l);
                sg[u].push_back(Node(v, l));
                sg[v].push_back(Node(u, l));
            }
    
            scanf("%d%d%d", &in, &out, &t);
            int ans = spfa();
            if (ans == -1) printf("Impossible\n");
            else printf("%d\n", ans);
        }
        return 0;
    }
    
    


  • 相关阅读:
    kvm虚拟迁移(5)
    kvm虚拟化网络管理(4)
    计算系数
    排列组合
    错排
    加分二叉树
    皇宫看守
    战略游戏
    数字转换
    JDK8 HashMap源码分析
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/3034371.html
Copyright © 2011-2022 走看看