zoukankan      html  css  js  c++  java
  • HDU 4725 The Shortest Path in Nya Graph

    The Shortest Path in Nya Graph

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)


    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
     
    Source
     

    题目大意:给n个点,m条无向边,边权w,为走这条路的代价。每个点属于某一层,从某层到隔壁层代价都是固定的c,求1到n最短路。

    因为每个点可以借助层的属性,到达其他点就有了其他的路径。所以有必要把每层也抽象出额外的点。因为每层的点也是不连通的,就是说如果点i和点j在同一层,并不代表他们之间距离就是0。所以对于层节点,还需要拆点。将每层的点拆成i+n和i + n + n 2个点。i+n表示进入第i层,i+n+n表示从第i层出去。建图的时候如果某点j属于第i层,那么

    j—>i + n连一条权为0的边,i + n + n —>j连一条权为0的边。对于层与层之间的关系,因为层抽象出来的点只是一个中间媒介点,所以对于进入第i层的边,只可能通过i+n这个点直接从隔壁层出去,于是i+n—>i +1 + n + n连边,边权c,i + n +1 —>i + n + n连边,边权c。注意虽然第i层被抽象出了i+n和I+ n + n2个点,但他们之间不能连边,因为同一层的点距离不为0,连边了就失去了拆点的意义。

    #include <iostream>
    #include <stdio.h>
    #include <string>
    #include <stdlib.h>
    #include <string.h>
    #include <algorithm>
    #include <math.h>
    #include <fstream>
    #include <vector>
    #include <queue>
    #define Min(a,b) ((a)<(b)?(a):(b))
    #pragma comment(linker, "/STACK:16777216")
    using namespace std ;
    typedef __int64 LL ;
    const int size=300008 ;
    const int inf=2000000000 ;
    struct Edge{
       int v ;
       int w ;
       int next ;
    };
    Edge  edge[size*3] ;
    int vec[size] ;
    int dist[size] ;
    int id ;
    int N , M , C;
    void init(){
       id=0 ;
       fill(vec,vec+1+3*N,-1) ;
       fill(dist,dist+1+3*N,inf) ;
    }
    inline void add_edge(int u ,int v ,int w){
         edge[id].v=v ;
         edge[id].w=w ;
         edge[id].next=vec[u] ;
         vec[u]=id++ ;
    }
    struct Node{
        int id ;
        int dis ;
        Node(){} ;
        Node(int i ,int d):id(i),dis(d){} ;
        friend bool operator <(const Node A ,const Node B){
            return A.dis>B.dis ;
        }
    };
    int bfs(){
       priority_queue<Node>que ;
       que.push(Node(1,0)) ;
       dist[1]=0 ;
       while(!que.empty()){
           Node now=que.top();
           que.pop() ;
           if(now.id==N)
               return  now.dis ;
           int u=now.id ;
           for(int e=vec[u];e!=-1;e=edge[e].next){
               int v=edge[e].v ;
               int w=edge[e].w ;
               if(now.dis+w<dist[v]){
                    dist[v]=now.dis+w ;
                    que.push(Node(v,dist[v])) ;
               }
           }
       }
       return -1 ;
    }
    int getint(){
        char c=getchar();
        int t=0;
        while(c<'0'||c>'9'){
            c=getchar();
        }
        while(c>='0'&&c<='9'){
           t=t*10+c-'0';
           c=getchar();
        }
       return t;
    }
    int gao(){
       int x ,u ,v ,w;
       N=getint() ;
       M=getint() ;
       C=getint() ;
       init() ;
       for(int i=1;i<=N;i++){
           u=getint() ;
           add_edge(i,u+N,0) ;
           add_edge(u+N+N,i,0) ;
       }
       for(int i=1;i<N;i++){
           add_edge(i+N,i+1+N+N,C) ;
           add_edge(i+1+N,i+N+N,C) ;
       }
       while(M--){
           u=getint() ;
           v=getint() ;
           w=getint() ;
           add_edge(u,v,w) ;
           add_edge(v,u,w) ;
       }
       if(N==0)
          return -1 ;
       if(N==1)
          return 0 ;
       return bfs() ;
    }
    int main(){
       int T ,k=1;
       cin>>T ;
       while(T--){
           printf("Case #%d: %d
    ",k++,gao()) ;
       }
       return 0 ;
    }
    

      

     
  • 相关阅读:
    Python学习第61天(html之form标签)
    Python学习第60天(html之body标签)
    Python学习第59天(web前端html /1))
    Python学习第58天(selector版本的ftp习题实现)
    Python学习第57天(异步IO)
    Python学习第56天(configpraser模块复习)
    Python学习第55天(IO多路复用)
    Python学习第54天(阻塞(blocking) IO和非阻塞(non-blocking)IO)
    如何通过Git Bash的命令行将电脑本地项目上传到自己的GitHub上
    第10周周博客
  • 原文地址:https://www.cnblogs.com/liyangtianmen/p/3318957.html
Copyright © 2011-2022 走看看