题目大意:
在Iokh市中,机场快线是市民从市内去机场的首选交通工具。机场快线分为经济线和商业线两种,线路,速度和价钱都不同。你有一张商业线车票,可以做一站商业线,而其他时候只能乘坐经济线。假设换乘时间忽略不计,你的任务是找一条去机场最快的路线(翻译来源:https://www.cnblogs.com/arbitrary/archive/2013/02/06/2908099.html)
题解:
预处理最短路,枚举商业线即可
PE了很久。。。郁闷。。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <algorithm> 6 #include <queue> 7 #include <vector> 8 #include <map> 9 #include <string> 10 #include <cmath> 11 #define min(a, b) ((a) < (b) ? (a) : (b)) 12 #define max(a, b) ((a) > (b) ? (a) : (b)) 13 #define abs(a) ((a) < 0 ? (-1 * (a)) : (a)) 14 template<class T> 15 inline void swap(T &a, T &b) 16 { 17 T tmp = a;a = b;b = tmp; 18 } 19 inline void read(int &x) 20 { 21 x = 0;char ch = getchar(), c = ch; 22 while(ch < '0' || ch > '9') c = ch, ch = getchar(); 23 while(ch <= '9' && ch >= '0') x = x * 10 + ch - '0', ch = getchar(); 24 if(c == '-') x = -x; 25 } 26 const int INF = 0x3f3f3f3f; 27 const int MAXN = 500 + 10; 28 const int MAXM = 1000 + 10; 29 struct Edge 30 { 31 int u,v,w,nxt; 32 Edge(int _u, int _v, int _w, int _nxt){u = _u;v = _v;w = _w;nxt = _nxt;} 33 Edge(){} 34 }edge[MAXM << 1]; 35 int head[MAXN], cnt, dis1[MAXN], dis2[MAXN], vis[MAXN]; 36 inline void insert(int a, int b, int c){edge[++ cnt] = Edge(a,b,c,head[a]), head[a] = cnt;} 37 struct Node 38 { 39 int u,w; 40 Node(int _u, int _w){u = _u, w = _w;} 41 Node(){} 42 }; 43 struct cmp 44 { 45 bool operator()(Node a, Node b) 46 { 47 return a.w > b.w; 48 } 49 }; 50 std::priority_queue<Node, std::vector<Node>, cmp> q; 51 void dij(int S, int *d, int size) 52 { 53 while(q.size()) q.pop(); 54 memset(d, 0x3f, size), memset(vis, 0, sizeof(vis)), d[S] = 0, q.push(Node(S, 0)); 55 while(q.size()) 56 { 57 Node now = q.top();q.pop(); 58 if(vis[now.u]) continue; 59 vis[now.u] = 1; 60 for(int pos = head[now.u];pos;pos = edge[pos].nxt) 61 { 62 int v = edge[pos].v; 63 if(vis[v]) continue; 64 if(d[v] > d[now.u] + edge[pos].w) d[v] = d[now.u] + edge[pos].w, q.push(Node(v, d[v])); 65 } 66 } 67 } 68 int n,s,t,m,ans1,u,v,w,k,tmp1,tmp2,tmp3,ans,from,to,flag,stack[MAXN],top; 69 void dfs(int u, int t, int *d) 70 { 71 if(u == t) 72 { 73 stack[++ top] = u, flag = 1;return; 74 } 75 for(int pos = head[u];pos;pos = edge[pos].nxt) 76 { 77 int v = edge[pos].v; 78 if(d[v] == d[u] + edge[pos].w) dfs(v, t, d); 79 if(flag) 80 { 81 stack[++ top] = u; 82 return; 83 } 84 } 85 } 86 int main() 87 { 88 int ttt = 0; 89 while(scanf("%d %d %d %d", &n, &s, &t, &m) != EOF) 90 { 91 if(ttt) putchar(' ');ttt = 1; 92 memset(head, 0, sizeof(head)), cnt = 0, ans = INF, from = to = 0; 93 for(int i = 1;i <= m;++ i) read(tmp1), read(tmp2), read(tmp3), insert(tmp1, tmp2, tmp3), insert(tmp2, tmp1, tmp3); 94 dij(s, dis1, sizeof(dis1)), dij(t, dis2, sizeof(dis2)), read(k); 95 ans = dis1[t]; 96 for(int i = 1;i <= k;++ i) 97 { 98 read(u), read(v), read(w); 99 if(ans > dis1[u] + w + dis2[v]) ans = dis1[u] + w + dis2[v], from = u, to = v; 100 if(ans > dis1[v] + w + dis2[u]) ans = dis1[v] + w + dis2[u], from = v, to = u; 101 } 102 if(ans == dis1[t]) 103 { 104 flag = top = 0, dfs(s, t, dis1); 105 int tt = 0; 106 for(int i = top;i >= 1;-- i) 107 if(!tt) printf("%d", stack[i]), tt = 1; 108 else printf(" %d", stack[i]); 109 printf(" Ticket Not Used "); 110 printf("%d ", dis1[t]); 111 continue; 112 } 113 flag = top = 0, dfs(s, from, dis1); 114 int tt = 0; 115 for(int i = top;i >= 1;-- i) 116 if(!tt) printf("%d", stack[i]), tt = 1; 117 else printf(" %d", stack[i]); 118 flag = top = 0, dfs(t, to, dis2); 119 for(int i = 1;i <= top;++ i) 120 if(!tt) printf("%d", stack[i]), tt = 1; 121 else printf(" %d", stack[i]); 122 printf(" %d %d ", from, ans); 123 } 124 return 0; 125 }