Airport Express (uva 11374)

Posted by lemming_ie on Wed, 15 Apr 2020 17:29:13 +0200

Title Link https://vjudge.net/problem/UVA-11374

meaning of the title
To get to the airport from the urban area, people need to take the airport express. The airport express is divided into two types: economic line and commercial line. You only have one commercial line ticket, and you can only take one commercial line. In other times, you can only take the economic line, ignore the transfer time, and find the fastest line to the airport.

thinking
For the example on page 329 of Dabaishu, you can first build a undirected graph according to the economic line, use dijkstra algorithm to find the shortest path with the starting point and the ending point as the source point, and then enumerate each economic line in turn to see if it can save time. If you can keep this scheme, see the code for details

#include<bits/stdc++.h>
using namespace std;

const int inf = 0x3f3f3f3f;
const int maxn = 550;
const int maxk = 1050;

struct Edge {
    int from, to, dist;
    Edge(int f, int t, int d) :from(f), to(t), dist(d) {}
};

struct HeapNode {
    int d, u;
    HeapNode(int dd, int uu) :d(dd), u(uu) {};
    bool operator < (const HeapNode& rhs) const {
        return d > rhs.d;
    }
};

struct Dijkstra {
    int n, m;           
    vector<Edge> edges; 
    vector<int> g[maxn];
    bool done[maxn];    
    int d[maxn];        
    int p[maxn];        

    void init(int n) {
        this->n = n;
        for (int i = 0; i < n; ++i) g[i].clear();   
        edges.clear();  
    }

    void add(int from, int to, int dist) {  
        edges.push_back(Edge(from, to, dist));
        m = edges.size();
        g[from].push_back(m - 1);
    }

    void dijkstra(int s) {  
        priority_queue<HeapNode> que;
        for (int i = 0; i < n; ++i) d[i] = inf;
        d[s] = 0;
        memset(done, 0, sizeof(done));
        que.push(HeapNode(0, s));
        while (!que.empty()) {
            HeapNode x = que.top();
            que.pop();
            int u = x.u;
            if (done[u]) continue;
            done[u] = true;
            for (int i = 0; i < g[u].size(); ++i) {
                Edge& e = edges[g[u][i]];
                if (d[e.to] > d[u] + e.dist) {
                    d[e.to] = d[u] + e.dist;
                    p[e.to] = g[u][i];
                    que.push(HeapNode(d[e.to], e.to));
                }
            }
        }
    }
};

int n, m, k, s, t;
int d1[maxn], d2[maxn];
int p1[maxn], p2[maxn];
Dijkstra di;

void print1(int x) {//Aiming at starting point
    if (x == s) {
        printf("%d", 1 + s);
        return;
    }
    Edge& e = di.edges[p1[x]];
    print1(e.from);
    printf(" %d", 1 + x);
}

void print2(int x) {//Aiming at the end point
    if (x == t) {
        printf(" %d\n", 1 + t);
        return;
    }
    printf(" %d", 1 + x);
    Edge& e = di.edges[p2[x]];
    print2(e.from);
}

int main() {
    int flag = 0;
    while (scanf("%d%d%d", &n, &s, &t) == 3) {
        --s, --t;
        if (flag) putchar('\n');
        flag = 1;

        di.init(n);
        scanf("%d", &m);
        for (int i = 0; i < m; ++i) {
            int u, v, c;
            scanf("%d%d%d", &u, &v, &c);
            --u, --v;
            di.add(u, v, c);
            di.add(v, u, c);
        }

        di.dijkstra(s);
        memcpy(d1, di.d, sizeof(d1));
        memcpy(p1, di.p, sizeof(p1));
        di.dijkstra(t);
        memcpy(d2, di.d, sizeof(d2));
        memcpy(p2, di.p, sizeof(p2));

        int ans = d1[t], sto = -1, tto = -1;

        scanf("%d", &k);
        for (int i = 0; i < k; ++i) {
            int u, v, c;
            scanf("%d%d%d", &u, &v, &c);
            --u, --v;
            if (d1[u] + c + d2[v] < ans) {
                ans = d1[u] + c + d2[v];
                sto = u;
                tto = v;
            }
            if (d1[v] + c + d2[u] < ans) {
                ans = d1[v] + c + d2[u];
                sto = v;
                tto = u;
            }
        }

        if (-1 == sto) {
            print1(t);
            printf("\n");
            printf("Ticket Not Used\n");
        }
        else {
            print1(sto);
            print2(tto);
            printf("%d\n", sto + 1);
        }
        printf("%d\n", ans);
    }
    return 0;
}