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
", slv.d[N] );
        else puts("-1");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/GBRgbr/p/3315517.html