uva 11374 Airport Express

题意:

有两种出行方式,一种是经济舱,一种是商务舱,商务舱比经济舱更加便捷。

一个人出行,想尽快达到目的地,但是他的钱不够,因此只能坐经济舱,但是幸运的是他有一张商务舱的票,意味着他可以选择坐一次商务舱,或者不坐(如果这样更省时间)。

给出地点数,起点,终点以及若干经济舱的线路和若干商务舱的线路,要求输出从起点到终点经过的点,以及是否使用了那张票,如果使用了,就输出使用的点,最后输出最短的时间。

思路:

首先不加商务舱的边,跑一次Dijkstra,求出不用票的最短时间;因为商务舱只能乘坐一次,而且K的值比较小,最大为1000,那么可以枚举每一条商务舱的边,每次加边,跑一次Dijkstra,求出最短时间,与不用票的最短时间进行比较,然后再把这条边去掉。

输出路径用两个fa数组记录前驱,递归输出路径。

代码:

  1 #include <stdio.h>
  2 #include <vector>
  3 #include <queue>
  4 #include <string.h>
  5 using namespace std;
  6 
  7 const int maxn = 505;
  8 const int inf = 0x3f3f3f3f;
  9 
 10 struct edge
 11 {
 12     int to,cost;
 13     edge(int uu,int vv)
 14     {
 15         to = uu;
 16         cost = vv;
 17     }
 18 };
 19 
 20 typedef pair<int,int> pii;
 21 
 22 vector<edge> g[maxn];
 23 int d[maxn],dd[maxn],fa1[maxn],fa2[maxn];
 24 
 25 void adde(int st,int to,int cost)
 26 {
 27     g[st].push_back(edge(to,cost));
 28 }
 29 
 30 void dijkstra(int s)
 31 {
 32     memset(d,inf,sizeof(d));
 33     memset(fa1,-1,sizeof(fa1));
 34     
 35     priority_queue<pii,vector<pii>,greater<pii> > pq;
 36     
 37     d[s] = 0;
 38     
 39     pq.push(pii(0,s));
 40     
 41     while (!pq.empty())
 42     {
 43         pii x = pq.top();pq.pop();
 44         
 45         int v = x.second;
 46         
 47         if (d[v] < x.first) continue;
 48         
 49         for (int i = 0;i < g[v].size();i++)
 50         {
 51              edge e = g[v][i];
 52             
 53             if (d[e.to] > d[v] + e.cost)
 54             {
 55                 d[e.to] = d[v] + e.cost;
 56                 pq.push(pii(d[e.to],e.to));
 57                 fa1[e.to] = v;
 58             }
 59         }
 60     }
 61 }
 62 
 63 int dijstra(int s)
 64 {
 65     memset(dd,inf,sizeof(dd));
 66     memset(fa2,-1,sizeof(fa2));
 67     
 68     priority_queue<pii,vector<pii>,greater<pii> > pq;
 69     
 70     dd[s] = 0;
 71     
 72     int use = -1;
 73     
 74     pq.push(pii(0,s));
 75     
 76     while (!pq.empty())
 77     {
 78         pii x = pq.top();pq.pop();
 79         
 80         int v = x.second;
 81         
 82         //printf("%d %d**
",v,x.first);
 83         
 84         
 85         if (dd[v] < x.first) continue;
 86         
 87         for (int i = 0;i < g[v].size();i++)
 88         {
 89              edge e = g[v][i];
 90             
 91             //printf("%d %d**
",v,e.to);
 92             
 93             if (dd[e.to] > dd[v] + e.cost)
 94             {
 95                 //printf("%d %d**
",e.to,dd[e]);
 96                 
 97                 dd[e.to] = dd[v] + e.cost;
 98                 pq.push(pii(dd[e.to],e.to));
 99                 
100                 //printf("%d %d**
",dd[e.to],e.to);
101                 
102                 if (dd[e.to] < d[e.to] && use == -1)
103                 {
104                     use = v;
105                 }
106                 
107                 fa2[e.to] = v;
108             }
109         }
110     }
111     
112     return use;
113 }
114 
115 void print1(int cur,int pre)
116 {
117     if (cur == -1)
118     {
119         return;
120     }
121     else
122     {
123         print1(fa1[cur],cur);
124         if (fa1[cur] == -1) printf("%d",cur);
125         else printf(" %d",cur);
126     }
127 }
128 
129 void print2(int cur,int pre)
130 {
131     if (cur == -1)
132     {
133         return;
134     }
135     else
136     {
137         print2(fa2[cur],cur);
138         if (fa2[cur] == -1) printf("%d",cur);
139         else printf(" %d",cur);
140     }
141 }
142 
143 
144 int main()
145 {
146     int n,s,e;
147     
148     int kase = 0;
149     
150     while (scanf("%d%d%d",&n,&s,&e) != EOF)
151     {
152         if (kase++) printf("
");
153         
154         for (int i = 0;i <= n;i++) g[i].clear();
155         
156         int m;
157         
158         scanf("%d",&m);
159         
160         for (int i = 0;i < m;i++)
161         {
162             int x,y,z;
163             
164             scanf("%d%d%d",&x,&y,&z);
165             
166             adde(x,y,z);
167             adde(y,x,z);
168         }
169         
170         dijkstra(s);
171         
172         int ma = -1;
173         int ans = d[e];
174         int xx,yy,zz;
175         
176         int k;
177         
178         scanf("%d",&k);
179         
180         for (int i = 0;i < k;i++)
181         {
182             int x,y,z;
183             
184             scanf("%d%d%d",&x,&y,&z);
185             
186             adde(x,y,z);
187             adde(y,x,z);
188             
189             dijstra(s);
190             
191             g[x].pop_back();
192             g[y].pop_back();
193             
194             //printf("%d %d**
",ans,dd[e]);
195             
196             if (dd[e] < ans)
197             {
198                 ans = dd[e];
199                 ma = i;
200                 xx = x;
201                 yy = y;
202                 zz = z;
203             }
204         }
205         
206         if (ma == -1)
207         {
208             print1(e,s);
209             printf("
");
210             printf("Ticket Not Used
");
211             printf("%d
",d[e]);
212         }
213         else
214         {
215             adde(xx,yy,zz);
216             adde(yy,xx,zz);
217             
218             int used = dijstra(s);
219             
220             print2(e,s);
221             printf("
");
222             printf("%d
%d
",used,dd[e]);
223         }
224     }
225     
226     return 0;
227 }
原文地址:https://www.cnblogs.com/kickit/p/8809293.html