UVa 11374 Airport Express

题目大意:
给你n个点和起点终点,再告诉你m条经济线路和k条商业线路,经济线路可以无限制经过,但商业线路只能乘坐一次,问从起点到达终点的最短距离和路径,并输出在什么位置换成商业线路。
分析:
枚举每一条商业线路, 计算在当前线路换乘的最小费用, 并更新距离即可,注意在这之前要预处理两次,分别从起点和终点出发计算距离和路径。
代码:

#include
using namespace std;
const int inf = 0x3f3f3f3f;
const int maxn = 500 + 10;

struct edge {
    int from, to, dist;
};
struct Heapnode { 
    int d, u;
    bool operator < (const Heapnode& rhs) const {
        return d > rhs.d;
    }
};
struct Dijkstra {
    int n, m;
    vector edges;
    vector<int> G[maxn];
    bool done[maxn];
    int dis[maxn], pre[maxn];

    void init(int n) {
        this -> n = n;
        for(int i=0; ivoid add_edge(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 Q;
        for(int i=0; i0; 
        memset(pre, 0, sizeof(pre));
        memset(done, false, sizeof(done));

        Q.push((Heapnode){0, s});
        while(!Q.empty()) {
            Heapnode x = Q.top(); Q.pop();
            int u = x.u; if(done[u]) continue; done[u] = true;

            for(int i=0; i<(int)G[u].size(); i++) {
                edge& e = edges[G[u][i]];
                if(dis[u] + e.dist < dis[e.to]) {
                    dis[e.to] = dis[u] + e.dist;
                    pre[e.to] = G[u][i];
                    Q.push((Heapnode){dis[e.to], e.to});
                }
            }
        }
    }
    void Getshortestpaths(int s, int *dist, vector<int>* paths) {
        dijkstra(s);
        for(int i=0; iint t = i;
            paths[i].push_back(t);
            while(t != s) {
                paths[i].push_back(edges[pre[t]].from);
                t = edges[pre[t]].from;
            }
            reverse(paths[i].begin(), paths[i].end());
        }
    }

}dij;

int u, v, w;
int n, m, k, s, t, Case;
int dis1[maxn], dis2[maxn];
vector<int> paths1[maxn], paths2[maxn];

void init() {
    s--, t--;
    dij.init(n);
    scanf("%d", &m);
    for(int i=0; iscanf("%d%d%d", &u, &v, &w); u--, v--;
        dij.add_edge(u, v, w); 
        dij.add_edge(v, u, w);
    }
}
int main() {
#ifndef ONLINE_JUDGE
    freopen("data.txt", "r", stdin);
    freopen("ans.txt", "w", stdout);
#endif
    while(scanf("%d%d%d", &n, &s, &t) == 3) {
        init();

        dij.Getshortestpaths(s, dis1, paths1);
        dij.Getshortestpaths(t, dis2, paths2);

        int Ticket = -1, Time = dis1[t];
        vector<int> path = paths1[t];

        scanf("%d", &k);
        for(int i=0; iscanf("%d%d%d", &u, &v, &w); u--, v--;
            for(int j=0; j<2; j++) {
                if(dis1[u] + w + dis2[v] < Time) {
                    Ticket = u;
                    Time = dis1[u] + w + dis2[v];
                    path = paths1[u];
                    for(int l=paths2[v].size() - 1; l>=0; l--) 
                        path.push_back(paths2[v][l]);
                }
                swap(u, v);
            }
        }
        if(Case++ > 0) printf("\n");
        for(int i=0; i<(int)path.size(); i++) 
            printf("%d%c", path[i] + 1, i == (int)path.size()-1 ? '\n' : ' '); 
        if(Ticket == -1) printf("Ticket Not Used\n"); else printf("%d\n", Ticket + 1);
        printf("%d\n", Time);
    }
    return 0;
}

你可能感兴趣的:(Graph,uva,图论,最短路)