zoukankan      html  css  js  c++  java
  • hdu 4725 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
      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <queue>
      5 #define N 100005
      6 #define inf 0x3f3f3f3f
      7 using namespace std;
      8 int n,m,C;
      9 struct Edges
     10 {
     11     int x,y,w,next;
     12 };
     13 struct HeapNode
     14 {
     15     int d;
     16     int u;
     17     bool operator < (const HeapNode& rhs) const{
     18         return d>rhs.d;
     19     }
     20 };
     21 priority_queue<HeapNode>Q;
     22 Edges e[N*10];
     23 int head[3*N];
     24 int dis[3*N];
     25 bool done[3*N];
     26 int k;
     27 
     28 void AddEdge(int x,int y,int w)
     29 {
     30     e[k].x=x,e[k].y=y,e[k].w=w,e[k].next=head[x],head[x]=k++;
     31 }
     32 int DJ()
     33 {
     34     memset(dis,inf,sizeof(dis));
     35     memset(done,false,sizeof(done));
     36     dis[1]=0;
     37     HeapNode p;
     38     p.d=dis[1];
     39     p.u=1;
     40     Q.push(p);
     41     while(!Q.empty())
     42     {
     43         HeapNode x = Q.top();
     44         Q.pop();
     45         int u=x.u;
     46         if(done[u])
     47         continue;
     48         done[u]=true;
     49         for(int i=head[u];i!=-1;i=e[i].next)
     50         {
     51             int y=e[i].y;
     52             int w=e[i].w;
     53             if(dis[u]+w<dis[y])
     54             {
     55                 dis[y]=dis[u]+w;
     56                 HeapNode temp;
     57                 temp.d=dis[y];
     58                 temp.u=y;
     59                 Q.push(temp);
     60             }
     61         }
     62     }
     63     return dis[n];
     64 }
     65 
     66 int main()
     67 {
     68     int t;
     69     scanf("%d",&t);
     70     int cas=1;
     71     while(t--)
     72     {
     73         scanf("%d%d%d",&n,&m,&C);
     74         memset(head,-1,sizeof(head));
     75         k=0;
     76         for(int i=1;i<=n;i++)
     77         {
     78             int num;
     79             scanf("%d",&num);
     80             AddEdge(i,n+2*num-1,0);
     81             AddEdge(n+2*num,i,0);
     82         }
     83         for(int i=1;i<n;i++)
     84         {
     85             AddEdge(n+2*i-1,n+2*(i+1),C);
     86             AddEdge(n+2*(i+1)-1,n+2*i,C);
     87         }
     88         for(int i=0;i<m;i++)
     89         {
     90             int x,y,z;
     91             scanf("%d%d%d",&x,&y,&z);
     92             AddEdge(x,y,z);
     93             AddEdge(y,x,z);
     94         }
     95         int res=DJ();
     96         if(res==inf)
     97         {
     98             printf("Case #%d: -1
    ",cas++);
     99         }
    100         else
    101         {
    102             printf("Case #%d: %d
    ",cas++,res);
    103         }
    104     }
    105     return 0;
    106 }
    View Code

    最短路问题,主要考的是构图的思想;

    思路:

    将每一层拆分成两个点,例如,第一层分成n+1即(n+2*i-1)和n+2(n+2*i);总共3*n个点;

    也就是第i层分成n+2*i-1和n+2*i;规定n+2*i-1始终作为入边,n+2*i始终作为出边;

    如果某个点属于第i层,就连边i->n+2*i-1,n+2*i->i,权值为0;

    然后根据题意,相邻的层次连边,权值为C,n+2*i-1->n+2*(i+1)和n+2*(i+1)-1->n+2*i;

    然后跟着输入的边构图;

    基本上这题的图构好之后,跑一边迪杰斯特拉+优先队列的模板,就能解决此题;



  • 相关阅读:
    诊断
    HIS内号码说明
    ASP.NET Page life cycle
    ASP.NET Simple page life cycle
    java多线程
    ibatis sqlmap
    cglib和asm
    利用ant编译maven项目
    Spring Cache与Tair结合
    USACO 1.2 MILKING COWS
  • 原文地址:https://www.cnblogs.com/ouyangduoduo/p/3315612.html
Copyright © 2011-2022 走看看