UVa 11374 机场快线
https://vjudge.net/problem/UVA-11374
题意:
机场快线分为经济线和商业线两种,线路、速度和价格都不同。你有一张商业线车票,可以坐一站商业线,而其他时候只能乘坐经济线。你的任务是找一条去机场最快的线路。
思路:
因为商业线只能坐一站,所有可以枚举坐的是哪一站,用dijkstra算出起点到每个点的最短时间f(x)和终点到每个点的最短时间g(x),则总时间为f(a)+T(a,b)+g(b),其中T(a,b)为从a坐一站商业线到达b的时间。
1 #include <iostream> 2 #include <cstring> 3 #include <algorithm> 4 #include <vector> 5 #include <queue> 6 using namespace std; 7 8 const int INF = 1000000000; 9 const int maxn = 500 + 5; 10 11 struct Edge 12 { 13 int from, to, dist; 14 Edge(int u, int v, int d) :from(u), to(v), dist(d){} 15 }; 16 17 struct HeapNode 18 { 19 int d, u; 20 HeapNode(int x, int y) :d(x), u(y){} 21 bool operator < (const HeapNode& rhs) const{ 22 return d > rhs.d; 23 } 24 }; 25 26 struct Dijkstra 27 { 28 int n, m; //点数和边数 29 vector<Edge> edges; //边列表 30 vector<int> G[maxn]; //每个结点出发的边编号(从0开始编号) 31 bool done[maxn]; //是否已永久标号 32 int d[maxn]; //s到各个点的距离 33 int p[maxn]; //最短路中的上一条边 34 35 void init(int n) 36 { 37 this->n = n; 38 for (int i = 0; i < n; i++) G[i].clear(); 39 edges.clear(); 40 } 41 42 void AddEdges(int from, int to, int dist) 43 { 44 edges.push_back(Edge(from,to,dist)); 45 m = edges.size(); 46 G[from].push_back((m - 1)); 47 } 48 49 void dijkstra(int s) 50 { 51 priority_queue<HeapNode> Q; 52 for (int i = 0; i < n; i++) d[i] = INF; 53 d[s] = 0; 54 memset(done, 0, sizeof(done)); 55 Q.push(HeapNode(0,s)); 56 while (!Q.empty()) 57 { 58 HeapNode x = Q.top(); Q.pop(); 59 int u = x.u; 60 if (done[u]) continue; 61 done[u] = true; 62 for (int i = 0; i < G[u].size(); i++) 63 { 64 Edge& e = edges[G[u][i]]; 65 if (d[e.to] > d[u] + e.dist) 66 { 67 d[e.to] = d[u] + e.dist; 68 p[e.to] = e.from; 69 Q.push(HeapNode(d[e.to],e.to)); 70 } 71 } 72 } 73 } 74 75 void getpath(int s, int e, vector<int>& path) 76 { 77 int pos = e; 78 while (true) 79 { 80 path.push_back(pos); 81 if (pos == s) 82 break; 83 pos = p[pos]; 84 } 85 } 86 87 }t[2]; 88 89 int N, S, E; 90 vector<int> path; 91 92 int main() 93 { 94 //freopen("D:\\input.txt", "r", stdin); 95 int time, kase = 0; 96 while (scanf("%d%d%d", &N, &S, &E) != EOF) 97 { 98 S--; E--; 99 if (kase != 0) printf("\n"); 100 kase++; 101 t[0].init(N); 102 t[1].init(N); 103 path.clear(); 104 int M, K; 105 int u, v, d; 106 scanf("%d", &M); 107 while (M--) 108 { 109 scanf("%d%d%d", &u, &v, &d); 110 u--; v--; 111 t[0].AddEdges(u, v, d); 112 t[1].AddEdges(u, v, d); 113 t[0].AddEdges(v, u, d); 114 t[1].AddEdges(v, u, d); 115 } 116 t[0].dijkstra(S); 117 t[1].dijkstra(E); 118 int ks = -1, ke = -1; 119 time = t[0].d[E]; 120 scanf("%d", &K); 121 while (K--) 122 { 123 scanf("%d%d%d", &u, &v, &d); 124 u--;v--; 125 if (d + t[0].d[u] + t[1].d[v] < time){ 126 time = d + t[0].d[u] + t[1].d[v]; 127 ks = u; ke = v; 128 } 129 if (d + t[0].d[v] + t[1].d[u] < time){ 130 time = d + t[0].d[v] + t[1].d[u]; 131 ks = v; ke = u; 132 } 133 } 134 if (ks == -1) 135 { 136 t[0].getpath(S, E, path); 137 reverse(path.begin(), path.end()); 138 for (int i = 0; i < path.size() - 1; i++) 139 printf("%d ", path[i]+1); 140 printf("%d\n", E+1); 141 printf("Ticket Not Used\n"); 142 printf("%d\n", time); 143 } 144 else 145 { 146 t[0].getpath(S, ks, path); 147 reverse(path.begin(), path.end()); 148 t[1].getpath(E, ke, path); 149 for (int i = 0; i < path.size() - 1; i++) 150 printf("%d ", path[i]+1 ); 151 printf("%d\n", E+1); 152 printf("%d\n", ks + 1); 153 printf("%d\n", time); 154 } 155 } 156 return 0; 157 }