• UVA


    Problem    UVA - 11374 - Airport Express

    Time Limit: 1000 mSec

    Problem Description

    In a small city called Iokh, a train service, Airport-Express, takes residents to the airport more quickly than other transports. There are two types of trains in Airport-Express, the Economy-Xpress and the Commercial-Xpress. They travel at different speeds, take different routes and have different costs. Jason is going to the airport to meet his friend. He wants to take the Commercial-Xpress which is supposed to be faster, but he doesn’t have enough money. Luckily he has a ticket for the Commercial-Xpress which can take him one station forward. If he used the ticket wisely, he might end up saving a lot of time. However, choosing the best time to use the ticket is not easy for him. Jason now seeks your help. The routes of the two types of trains are given. Please write a program to find the best route to the destination. The program should also tell when the ticket should be used.

    Input

    The input consists of several test cases. Consecutive cases are separated by a blank line. The first line of each case contains 3 integers, namely N, S and E (2 ≤ N ≤ 500,1 ≤ S,E ≤ N), which represent the number of stations, the starting point and where the airport is located respectively. There is an integer M (1 ≤ M ≤ 1000) representing the number of connections between the stations of the Economy-Xpress. The next M lines give the information of the routes of the Economy-Xpress. Each consists of three integers X, Y and Z (X,Y ≤ N,1 ≤ Z ≤ 100). This means X and Y are connected and it takes Z minutes to travel between these two stations. The next line is another integer K (1 ≤ K ≤ 1000) representing the number of connections between the stations of the Commercial-Xpress. The next K lines contain the information of the CommercialXpress in the same format as that of the Economy-Xpress. All connections are bi-directional. You may assume that there is exactly one optimal route to the airport. There might be cases where you MUST use your ticket in order to reach the airport.

    Output

    For each case, you should first list the number of stations which Jason would visit in order. On the next line, output ‘Ticket Not Used’ if you decided NOT to use the ticket; otherwise, state the station where Jason should get on the train of Commercial-Xpress. Finally, print the total time for the journey on the last line. Consecutive sets of output must be separated by a blank line.

    Sample Input

    4 1 4 4 1 2 2 1 3 3 2 4 4 3 4 5 1 2 4 3

    Sample Output

    1 2 4

    2

    5

    题解:考虑枚举用哪个商业票,为什么这么想呢,因为堆优化Dijkstra复杂度(n+m)logn,乘上个K,如果没有多组数据的话应该是能过的,其实可以做到更好,分别从起点和终点跑两遍最短路,这样对于枚举的用商业票的那一段来说就可以常数时间内算出总费用,因为最短路一定是w(u, v) + dist[u](起点到u最短路) + dist2[v](v到终点最短路),这样问题就在O(K)时间内解决了。

      1 #include <bits/stdc++.h>
      2 
      3 using namespace std;
      4 
      5 #define REP(i, n) for (int i = 1; i <= (n); i++)
      6 #define sqr(x) ((x) * (x))
      7 
      8 const int maxn = 10000 + 10;
      9 const int maxm = 20000 + 10;
     10 const int maxs = 10000 + 10;
     11 
     12 typedef long long LL;
     13 typedef pair<int, int> pii;
     14 typedef pair<double, double> pdd;
     15 
     16 const LL unit = 1LL;
     17 const int INF = 0x3f3f3f3f;
     18 const LL mod = 1000000007;
     19 const double eps = 1e-14;
     20 const double inf = 1e15;
     21 const double pi = acos(-1.0);
     22 
     23 struct Edge
     24 {
     25     int to, w, next;
     26 } edge[maxm];
     27 
     28 struct HeapNode
     29 {
     30     int dis, u;
     31     bool operator<(const HeapNode &a) const
     32     {
     33         return dis > a.dis;
     34     }
     35 };
     36 
     37 int tot, head[maxn];
     38 int n, m, k;
     39 int st, en;
     40 
     41 void init()
     42 {
     43     tot = 0;
     44     memset(head, -1, sizeof(head));
     45 }
     46 
     47 void AddEdge(int u, int v, int w)
     48 {
     49     edge[tot].to = v;
     50     edge[tot].w = w;
     51     edge[tot].next = head[u];
     52     head[u] = tot++;
     53 }
     54 
     55 int dist[maxn], dist2[maxn];
     56 int pre[maxn], Next[maxn];
     57 bool vis[maxn];
     58 
     59 int Dijkstra()
     60 {
     61     memset(dist, INF, sizeof(dist));
     62     memset(vis, false, sizeof(vis));
     63     memset(pre, -1, sizeof(pre));
     64     priority_queue<HeapNode> que;
     65     pre[st] = st;
     66     dist[st] = 0;
     67     que.push((HeapNode){0, st});
     68     while (!que.empty())
     69     {
     70         HeapNode first = que.top();
     71         que.pop();
     72         int u = first.u;
     73         if (vis[u])
     74             continue;
     75         vis[u] = true;
     76         for (int i = head[u]; i != -1; i = edge[i].next)
     77         {
     78             int v = edge[i].to;
     79             if (dist[v] > dist[u] + edge[i].w)
     80             {
     81                 pre[v] = u;
     82                 dist[v] = dist[u] + edge[i].w;
     83                 que.push((HeapNode){dist[v], v});
     84             }
     85         }
     86     }
     87     return dist[en];
     88 }
     89 
     90 void Dijkstra2()
     91 {
     92     memset(dist2, INF, sizeof(dist2));
     93     memset(vis, false, sizeof(vis));
     94     memset(Next, -1, sizeof(Next));
     95     priority_queue<HeapNode> que;
     96     dist2[en] = 0;
     97     Next[en] = en;
     98     que.push((HeapNode){0, en});
     99     while (!que.empty())
    100     {
    101         HeapNode first = que.top();
    102         que.pop();
    103         int u = first.u;
    104         if (vis[u])
    105             continue;
    106         vis[u] = true;
    107         for (int i = head[u]; i != -1; i = edge[i].next)
    108         {
    109             int v = edge[i].to;
    110             if (dist2[v] > dist2[u] + edge[i].w)
    111             {
    112                 Next[v] = u;
    113                 dist2[v] = dist2[u] + edge[i].w;
    114                 que.push((HeapNode){dist2[v], v});
    115             }
    116         }
    117     }
    118 }
    119 
    120 int main()
    121 {
    122     ios::sync_with_stdio(false);
    123     cin.tie(0);
    124     //freopen("input.txt", "r", stdin);
    125     //freopen("output.txt", "w", stdout);
    126     bool ok = false;
    127     while (cin >> n >> st >> en)
    128     {
    129         init();
    130         cin >> m;
    131         int x, y, z;
    132         for (int i = 0; i < m; i++)
    133         {
    134             cin >> x >> y >> z;
    135             AddEdge(x, y, z);
    136             AddEdge(y, x, z);
    137         }
    138         int Min = Dijkstra();
    139         //cout << "Min:" << Min << endl;
    140         Dijkstra2();
    141         cin >> k;
    142         int ansu = -1, ansv = -1;
    143         for(int i = 0; i < k; i++)
    144         {
    145             cin >> x >> y >> z;
    146             if(dist[x] + z + dist2[y] < Min)
    147             {
    148                 Min = dist[x] + z + dist2[y];
    149                 ansu = x, ansv = y;
    150             }
    151             if(dist[y] + z + dist2[x] < Min)
    152             {
    153                 Min = dist[y] + z + dist2[x];
    154                 ansu = y, ansv = x;
    155             }
    156         }
    157         if(!ok)
    158             ok = true;
    159         else
    160             cout << endl;
    161         //cout << "Min:" << Min << endl;
    162         if(ansu == -1 && ansv == -1)
    163         {
    164             int tmp = st;
    165             while(tmp != en)
    166             {
    167                 cout << tmp << " ";
    168                 tmp = Next[tmp];
    169             }
    170             cout << en << endl;
    171             cout << "Ticket Not Used" << endl;
    172             cout << Min << endl;
    173         }
    174         else
    175         {
    176             int tmp = ansu;
    177             stack<int> ans;
    178             while(!ans.empty())
    179                 ans.pop();
    180             while(tmp != st)
    181             {
    182                 ans.push(tmp);
    183                 tmp = pre[tmp];
    184             }
    185             ans.push(st);
    186             while(!ans.empty())
    187             {
    188                 cout << ans.top() << " ";
    189                 ans.pop();
    190             }
    191             tmp = ansv;
    192             while (tmp != en)
    193             {
    194                 cout << tmp << " ";
    195                 tmp = Next[tmp];
    196             }
    197             cout << en << endl;
    198             cout << ansu << endl;
    199             cout << Min << endl;
    200         }
    201     }
    202     return 0;
    203 }
  • 相关阅读:
    打包CAB大全
    设置VC6为默认异常调试工具
    XP系统遍历所有进程
    编写有界面的系统服务程序
    GOOGLE C++编程规范
    编写有界面的系统服务程序
    VC下音频文件的播放
    用MFC建立COM服务器对象的框架步骤
    注册OCX失败:由于应用程序配置不正确,程序未能启动.重新安装应用程序可能会纠正这个错误
    MediaPlayer属性大全
  • 原文地址:https://www.cnblogs.com/npugen/p/10757913.html
Copyright © 2020-2023  润新知