HDU 4725 The Shortest Path in Nya Graph( 建图 + 最短路 )

主要是建图,建好图之后跑一边dijkstra即可。

一共3N个点,1~N是原图中的点1~N,然后把每层x拆成两个点(N+x)[用于连指向x层的边]和(N+N+x)[用于连从x层指出的边]。

相邻层节点互相可达:AddEdge( N+N+x+1, N+x, C), AddEdge( N+N+x, N+x+1, C);

对于位于x层的节点i,AddEdge(N+x, i, 0), AddEdge(i, N+N+x, 0);

 

#include <cstdio>

#include <cstring>

#include <cstdlib>

#include <algorithm>

#include <queue>



using namespace std;



const int MAXN = 100010*3;

const int INF  = 1 << 30;



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) { }

};



struct Dijkstra

{

    int n, m;

    vector<Edge> edges;

    vector<int> G[MAXN];

    bool done[MAXN];

    int d[MAXN], p[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 )

    {

        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 < (int)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;

    }

};



int N, M, C;

Dijkstra slv;

bool vis[MAXN/3];



int main()

{

    int T, cas = 0;

    scanf( "%d", &T );

    while ( T-- )

    {

        scanf( "%d%d%d", &N, &M, &C );



        memset( vis, false, sizeof(bool)*(N+2) );

        slv.init( N*3 );



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

        {

            int layer;

            scanf( "%d", &layer );

            slv.AddEdge( N + layer, i, 0 );

            slv.AddEdge( i, N + N + layer, 0 );

            vis[layer] = true;

        }



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

        {

            if ( vis[i] && vis[i + 1] )

            {

                slv.AddEdge( N + N + i, N + i + 1, C );

                slv.AddEdge( N + N + i + 1, N + i, C );

            }

        }



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

        {

            int u, v, w;

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

            slv.AddEdge( u, v, w );

            slv.AddEdge( v, u, w );

        }



        slv.dijkstra( 1 );



        printf( "Case #%d: ", ++cas );

        if ( slv.d[N] < INF ) printf( "%d\n", slv.d[N] );

        else puts("-1");

    }

    return 0;

}

 

你可能感兴趣的:(Graph)