UVa 11374 - Airport Express ( dijkstra预处理 )

起点和终点各做一次单源最短路, d1[i], d2[i]分别代表起点到i点的最短路和终点到i点的最短路,枚举商业线车票cost(a, b);  ans = min( d1[a] + cost(a, b) + d2[b] );

#include <cstdio>

#include <cstring>

#include <cstdlib>

#include <algorithm>

#include <vector>

#include <queue>



using namespace std;



const int MAXN = 1010;

const int INF  = 1 << 22;



struct HeapNode

{

    int d, u;

    HeapNode() { }

    HeapNode( int _d, int _u ): d(_d), u(_u) { }

    bool operator<( const HeapNode& rhs ) const

    {

        return d > rhs.d;

    }

};



struct Edge

{

    int from, to, dist;

    Edge() { }

    Edge( int f, int t, int d ) : from(f), to(t), dist(d) { }

};



int N, S, E;



struct Dijkstra

{

    int n, m;

    vector<Edge> edges;

    vector<int> G[MAXN];

    bool done[MAXN];

    int d1[MAXN];

    int d2[MAXN];

    int p1[MAXN];

    int p2[MAXN];



    void init( int n )

    {

        this->n = n;

        for ( int i = 0; i <= n; ++i ) G[i].clear();

        edges.clear();

        return;

    }



    void AddEdge( int from, int to, int dist )

    {

        edges.push_back( Edge( from, to, dist ) );

        m = edges.size();

        G[from].push_back(m - 1);

        return;

    }

    

    void dijkstra( int s, int *d, int *p )

    {

        priority_queue<HeapNode> Q;

        for ( int i = 0; i <= n; ++i ) d[i] = INF;

        d[s] = 0;

        memset( done, 0, 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.to] > d[u] + e.dist )

                {

                    d[e.to] = d[u] + e.dist;

                    p[e.to] = G[u][i];

                    Q.push( HeapNode( d[e.to], e.to ) );

                }

            }

        }

        return;

    }



    void Print1( int e )

    {

        if ( e == S )

        {

            printf( "%d", S );

            return;

        }

        Edge& tp = edges[ p1[e] ];

        Print1( tp.from );

        printf( " %d", e );

        return;

    }



    void Print2( int e )

    {

        if ( e == E )

        {

            printf( " %d", E );

            return;

        }

        Edge& tp = edges[ p2[e] ];

        printf( " %d", e );

        Print2( tp.from );

        return;

    }



};



int M, K;

Dijkstra slv;

vector<Edge> ec;  //经济线路



int main()

{

    //freopen( "UVa_11374.in", "r", stdin );

    //freopen( "UVa_11374.out", "w", stdout );

    int cas = 0;

    while ( scanf( "%d%d%d", &N, &S, &E ) == 3 )

    {

        slv.init( N );

        scanf( "%d", &M );

        for ( int i = 0; i < M; ++i )

        {

            int u, v, cost;

            scanf( "%d%d%d", &u, &v, &cost );

            slv.AddEdge( u, v, cost );

            slv.AddEdge( v, u, cost );

        }

        

        ec.clear();

        scanf( "%d", &K );

        for ( int i = 0; i < K; ++i )

        {

            int u, v, cost;    

            scanf( "%d%d%d", &u, &v, &cost );

            ec.push_back( Edge(u, v, cost) );

        }



            slv.dijkstra( S, slv.d1, slv.p1 );

        slv.dijkstra( E, slv.d2, slv.p2 );



//        for ( int i = 1; i <= N; ++i )

//        {

//            printf("%d %d\n", slv.d1[i], slv.d2[i] );

//        }

        

        int ans = slv.d1[E];

        int huan = -1;

        int huaned;



        for ( int i = 0; i < K; ++i )

        {

            int u = ec[i].from;

            int v = ec[i].to;

            int tmp1 = slv.d1[u] + ec[i].dist + slv.d2[v];

            int tmp2 = slv.d1[v] + ec[i].dist + slv.d2[u];

            if ( tmp1 < ans )

            {

                ans = tmp1;

                huan = u;

                huaned = v;

            }

            if ( tmp2 < ans )

            {

                ans = tmp2;

                huan = v;

                huaned = u;

            }

        }



        if (cas) puts("");

        ++cas;



        if ( huan == -1 ) 

        {

            slv.Print1(E);

            puts("");

            puts("Ticket Not Used");

        }

        else

        {

            slv.Print1(huan);

            slv.Print2(huaned);

            puts("");

            printf( "%d\n", huan );

        }

        printf( "%d\n", ans );



    }

    return 0;

}

 

你可能感兴趣的:(dijkstra)