The Shortest Path in Nya Graph

Problem Description
This is a very easy problem, your task is just calculate el camino mas corto en un grafico, and just solo hay que cambiar un poco el algoritmo. If you do not understand a word of this paragraph, just move on.
The Nya graph is an undirected graph with "layers". Each node in the graph belongs to a layer, there are N nodes in total.
You can move from any node in layer x to any node in layer x + 1, with cost C, since the roads are bi-directional, moving from layer x + 1 to layer x is also allowed with the same cost.
Besides, there are M extra edges, each connecting a pair of node u and v, with cost w.
Help us calculate the shortest path from node 1 to node N.
 
Input
The first line has a number T (T <= 20) , indicating the number of test cases.
For each test case, first line has three numbers N, M (0 <= N, M <= 105) and C(1 <= C <= 103), which is the number of nodes, the number of extra edges and cost of moving between adjacent layers.
The second line has N numbers li (1 <= li <= N), which is the layer of ith node belong to.
Then come N lines each with 3 numbers, u, v (1 <= u, v < =N, u <> v) and w (1 <= w <= 104), which means there is an extra edge, connecting a pair of node u and v, with cost w.
 
Output
For test case X, output "Case #X: " first, then output the minimum cost moving from node 1 to node N.
If there are no solutions, output -1.
 
Sample Input

2
3 3 3
1 3 2
1 2 1
2 3 1
1 3 3

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

 
Sample Output
Case #1: 2
Case #2: 3

 

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
typedef pair<int, int> PII;

const int MAXN = 300010;
const int MAXE = MAXN * 2;

int head[MAXN];
int to[MAXE], next[MAXE], cost[MAXE];
int n, m, ecnt,c;

void init()
{
    memset(head, 0, sizeof(head));
    ecnt = 1;
}

inline void add_edge(int u, int v, int c)
{
    to[ecnt] = v;
    cost[ecnt] = c;
    next[ecnt] = head[u];
    head[u] = ecnt++;
}

int dis[MAXN];
int lay[MAXN];
bool vis[MAXN];

void Dijkstra(int st, int ed)
{
    memset(dis, 0x7f, sizeof(dis));
    memset(vis, 0, sizeof(vis));
    priority_queue<PII> que;
    que.push(make_pair(0, st));
    dis[st] = 0;
    while(!que.empty())
    {
        int u = que.top().second;
        que.pop();
        if(vis[u]) continue;
        if(u == ed) return ;
        vis[u] = true;
        for(int p = head[u]; p; p = next[p])
        {
            int &v = to[p];
            if(dis[v] > dis[u] + cost[p])
            {
                dis[v] = dis[u] + cost[p];
                que.push(make_pair(-dis[v], v));
            }
        }
    }
    return ;
}
/*有n个点m条无向边,每个点有一个层次,相邻层次的点可以移动,花费为C,问1~n的最小花费。
思路:每层新建两个点a、b,i层的点到ai连一条费用为0的边,bi到i层的点连一条费用为0的边,
然后相邻的层分别从ai到bj连一条边,费用为C。跑Dijkstra+heap可AC。*/
int main()
{
   int T;
   scanf("%d",&T);
    for(int t = 1; t <= T; ++t)
    {
        scanf("%d %d %d",&n,&m,&c);
        init();
        for(int i = 1; i <= n; ++i)
        {
            scanf("%d",&lay[i]);
            add_edge(i, n + 2*lay[i]-1, 0);
            add_edge(n + 2*lay[i], i, 0);
        }
        for(int i = 1; i < n; ++i)
        {
            add_edge(n + 2*i-1, n+2*(i+1), c);
            add_edge(n + 2*(i+1)-1, n+2*i, c);
        }
        int u, v, w;
        while(m--)
        {
            scanf("%d%d%d", &u, &v, &w);
            add_edge(u, v, w);
            add_edge(v, u, w);
        }
        Dijkstra(1, n);
        if(dis[n] == 0x7f7f7f7f) dis[n] = -1;
        printf("Case #%d: %d\n", t, dis[n]);
    }
    return 0;
}
最短路(HDU4725)

 

 

posted @ 2013-09-13 19:42  1002liu  阅读(233)  评论(0编辑  收藏  举报