UVA 11374 - Airport Express
题意:给定一些经济线,和一些商务线,商务线最多坐一次,每个线有一个时间,问最短时间
思路:从起点,终点各做一次dijstra,然后枚举商务线,就可以算出总时间,最后求出总时间最少
代码:
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;
#define INF 0x3f3f3f3f
const int MAXNODE = 505;
struct Edge {
int u, v, dist;
Edge() {}
Edge(int u, int v, int dist) {
this->u = u;
this->v = v;
this->dist = dist;
}
};
struct HeapNode {
int d, u;
HeapNode() {}
HeapNode(int d, int u) {
this->d = d;
this->u = u;
}
bool operator < (const HeapNode& c) const {
return d > c.d;
}
};
struct Dijkstra {
int n, m;
vector<Edge> edges;
vector<int> g[MAXNODE];
bool done[MAXNODE];
int d[MAXNODE], p[MAXNODE];
void init(int tot) {
n = tot;
for (int i = 0; i < n; i++)
g[i].clear();
edges.clear();
}
void add_Edge(int u, int v, int dist) {
edges.push_back(Edge(u, v, dist));
m = edges.size();
g[u].push_back(m - 1);
}
void print(int s, int e) {//shun xu
if (s == e) {
printf("%d", e + 1);
return;
}
print(s, edges[p[e]].u);
printf(" %d", e + 1);
}
void print2(int s, int e) {//ni xu
if (s == e) {
printf("%d\n", e + 1);
return;
}
printf("%d ", e + 1);
print2(s, edges[p[e]].u);
}
void dijkstra(int s) {
priority_queue<HeapNode> Q;
for (int i = 0; i < n; i++) d[i] = INF;
d[s] = 0;
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 < g[u].size(); i++) {
Edge& e = edges[g[u][i]];
if (d[e.v] > d[u] + e.dist) {
d[e.v] = d[u] + e.dist;
p[e.v] = g[u][i];
Q.push(HeapNode(d[e.v], e.v));
}
}
}
}
} gao1, gao2;
const int M = 2005;
int n, s, e;
Edge em[M];
int main() {
int bo = 0;
while (~scanf("%d%d%d", &n, &s, &e)) {
if (bo) printf("\n");
else bo = 1;
gao1.init(n);
gao2.init(n);
s--; e--;
int m, x, y, z;
scanf("%d", &m);
while (m--) {
scanf("%d%d%d", &x, &y, &z);
x--; y--;
gao1.add_Edge(x, y, z);
gao1.add_Edge(y, x, z);
gao2.add_Edge(x, y, z);
gao2.add_Edge(y, x, z);
}
scanf("%d", &m);
for (int i = 0; i < m; i++) {
scanf("%d%d%d", &x, &y, &z);
x--; y--;
em[i * 2] = Edge(x, y, z);
em[i * 2 + 1] = Edge(y, x, z);
}
gao1.dijkstra(s);
gao2.dijkstra(e);
int ans = gao1.d[e];
int ss = e, ee = -1;
for (int i = 0; i < 2 * m; i++) {
int u = em[i].u, v = em[i].v, dist = em[i].dist;
int sum = gao1.d[u] + gao2.d[v] + dist;
if (sum < ans) {
ans = sum;
ss = u;
ee = v;
}
}
gao1.print(s, ss);
if (ee != -1) {
printf(" ");
gao2.print2(e, ee);
}
else printf("\nTicket Not Used\n");
if (ee != -1) printf("%d\n", ss + 1);
printf("%d\n", ans);
}
return 0;
}