Uva 11374 - Airport Express(枚举+最短路)

题目链接 https://vjudge.net/problem/UVA-11374

【题意】
市民从市区去机场要走机场快线,机场快线分为经济线和商业线两种,你只有一张商业线车票,只能坐一站商业线,其它时候只能坐经济线,忽略换乘时间,找到一条去机场最快的线路。

【思路】
大白书329页例题,可以先按照经济线建立无向图,用dijkstra算法分别求出以起点和以终点为源点的最短路,然后依次枚举每种经济线,看看能不能更省时间,如果能就保留这种方案,具体细节看代码

#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) {//针对起点
    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) {//针对终点
    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;
}
posted @ 2018-02-05 20:00  不想吃WA的咸鱼  阅读(300)  评论(0编辑  收藏  举报