hdu4725最短路变形 添加点

The Shortest Path in Nya Graph

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4872    Accepted Submission(s): 1122


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
 
 
 
题意: 有n个地点,m条边,每条边耗费w,每个点又属于一些集合,相邻的集合之间的点可以直接通行,耗费c。现在求1到n的最少费用。
 
思路:可以把集合当做一个点,从集合到集合内的点费用为0,点到相邻的集合费用为c,这样就既保证了不用暴力枚举相邻集合里面的每个点,有保证相邻集合里的点的最短路(表达能力不好 -。-#!)。
就是这张图的意思:
然后一遍dij+heap就好。
 
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<string>
#include<time.h>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define INF 1000000001
#define ll long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
const int MAXN = 100010;
struct node
{
    int to;
    int val;
    int next;
}edge[MAXN * 10];
int pre[MAXN*3],vis[MAXN*3],dis[MAXN*3],n,m,k,c,ind;
int num[MAXN],ok[MAXN];
void add(int x,int y,int z)
{
    edge[ind].to = y;
    edge[ind].val = z;
    edge[ind].next = pre[x];
    pre[x] = ind ++;
}
struct Node
{
    int p;
    ll val;
    Node(){}
    Node(int fp,int fval):p(fp),val(fval){}
    friend bool operator < (Node fa,Node fb){
        return fa.val > fb.val;
    }
};
void dij(int s)
{
    priority_queue<Node>fq;
    for(int i = 1; i <= k; i++){
        dis[i] = INF;
        vis[i] = 0;
    }
    dis[s] = 0;
    fq.push(Node(s,0));
    while(!fq.empty()){
        Node tp = fq.top();
        fq.pop();
        vis[tp.p] = 1;
        for(int i = pre[tp.p]; i != -1; i = edge[i].next){
            int t = edge[i].to;
            if(!vis[t] && dis[t] > dis[tp.p] + edge[i].val){
                dis[t] = dis[tp.p] + edge[i].val;
                fq.push(Node(t,dis[t]));
            }
        }
    }
}
int main()
{
    int t,ff = 0;
    scanf("%d",&t);
    while(t--){
        memset(num,0,sizeof(num));
        memset(ok,0,sizeof(ok));
        scanf("%d%d%d",&n,&m,&c);
        int x;
        ind = 0;
        memset(pre,-1,sizeof(pre));
        for(int i = 1; i <= n; i++){
            scanf("%d",&x);
            ok[x] = 1;
            num[i] = x;
        }
        for(int i = 1; i <= n; i++){//点与集合之间连边
            add(n+num[i],i,0);
            if(num[i] > 1)add(i,n+num[i]-1,c);
            if(num[i] < n)add(i,n+num[i]+1,c);
        }
        int y,z;
        for(int i = 1; i <= m; i++){
            scanf("%d%d%d",&x,&y,&z);
            add(x,y,z);
            add(y,x,z);
        }
        //cout<<k<<endl;
        k = 2 * n;
        dij(1);
        printf("Case #%d: ",++ff);
        if(dis[n] >= INF){
            printf("-1\n");
        }
        else {
            printf("%d\n",dis[n]);
        }
    }
    return 0;
}

 

 

 

posted @ 2016-05-05 22:29  sweat123  阅读(333)  评论(0编辑  收藏  举报