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;

}




 

 

你可能感兴趣的:(ZOJ)