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

    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.

    InputThe 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 <= 10 5) and C(1 <= C <= 10 3), which is the number of nodes, the number of extra edges and cost of moving between adjacent layers.
    The second line has N numbers l i (1 <= l i <= N), which is the layer of i th node belong to. 
    Then come N lines each with 3 numbers, u, v (1 <= u, v < =N, u <> v) and w (1 <= w <= 10 4), which means there is an extra edge, connecting a pair of node u and v, with cost w.OutputFor 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,C 表示 N 个点和 M条边,每两层之间通过的费用是 C
    意思就是,除了走给定的路之外,我们还可以选择穿透层次,花费 C 的费用走到上一层或者下一层的任意一个节点,而不去走题目给定的边。
    然后第二行 N个数就是表示第 i 个节点的层号,然后 M 行是描述边的。

    思路:由于数据太大,一次可以设想每层都有一个入口和出口,层内的点到出口的距离为0,同样入口也是,层与层之间通过
    让每层只出不进的出口连接上下两层只进不出的入口,权值是c,层内点与点之间的初始距离为无穷,有额外边的为额外值。
    这样有N个初始的点,外加N个入口和N个出口,总共有3*N个点,边的数量也要变大。我将第N+1到2*N的点设为出口,将2*N+1到3*N之间的点
    设为入口,具体内容见代码。

    代码:
      1 #include <cstdio>
      2 #include <fstream>
      3 #include <algorithm>
      4 #include <cmath>
      5 #include <deque>
      6 #include <vector>
      7 #include <queue>
      8 #include <string>
      9 #include <cstring>
     10 #include <map>
     11 #include <stack>
     12 #include <set>
     13 #include <sstream>
     14 #include <iostream>
     15 #define mod 998244353
     16 #define eps 1e-6
     17 #define ll long long
     18 #define INF 0x3f3f3f3f
     19 using namespace std;
     20 
     21 //数据开到比n*3要大
     22 const int maxn = 1000005;
     23 //结构体定义边的信息
     24 struct node1 
     25 {
     26     int y,z,next;
     27 };
     28 node1 no[maxn];
     29 //结构体定义为优先结构
     30 struct node2
     31 {
     32     //x表示当前点,len表示从起点到x的权值
     33     int x,len;
     34     friend bool operator < (node2 a,node2 b)
     35     {
     36         return a.len>b.len;
     37     }
     38 };
     39 //t表示测试样例数,n表示点数,m表示额外边数,p表示层与层之间的权值
     40 int t,n,m,p;
     41 //存放边的位置
     42 int head[maxn];
     43 //存放起点到其他点的最短距离
     44 int dis[maxn];
     45 //标记是否为最短点
     46 bool vis[maxn];
     47 //表示边的数量
     48 int s;
     49 //函数用于储存边的信息
     50 //表示从x到y的权值为z
     51 void add(int x,int y,int z)
     52 {
     53     no[s].y=y;
     54     no[s].z=z;
     55     no[s].next=head[x];
     56     head[x]=s++;
     57 }
     58 //初始化层与层之间入口与出口的连接
     59 //a表示层数,b表示层之间的权值
     60 void init(int a,int b)
     61 {
     62     add(a+1,2*n+2,b);
     63     for(int i=2;i<n;i++)
     64     {
     65         add(n+i,2*n+i-1,b);
     66         add(n+i,2*n+i+1,b);
     67     }
     68     add(2*n,3*n-1,b);
     69 }
     70 //函数求最短路
     71 void spfa()
     72 {
     73     //定义优先队列
     74     priority_queue<node2> qu;
     75     node2 q;
     76     //初始化数据
     77     memset(vis,0,sizeof(vis));
     78     memset(dis,INF,sizeof(dis));
     79     dis[1]=0;
     80     q.x=1;
     81     q.len=0;
     82     //起点为1,权值为0
     83     qu.push(q);
     84     while(!qu.empty())
     85     {
     86         q=qu.top();
     87         qu.pop();
     88         //如果当前点已找过,则无需再找
     89         if(vis[q.x])
     90         {
     91             continue;
     92         }
     93         //标记此点已找过
     94         vis[q.x]=1;
     95         //遍历此点连接的边
     96         for(int i=head[q.x];i!=-1;i=no[i].next)
     97         {
     98             int u=no[i].y;
     99             int v=no[i].z;
    100             //更新起点到u的最小值
    101             if(dis[u]>dis[q.x]+v)
    102             {
    103                 dis[u]=dis[q.x]+v;
    104                 //将此点入队
    105                 node2 s;
    106                 s.x=u;
    107                 s.len=dis[u];
    108                 qu.push(s);
    109             }
    110         }
    111     }
    112 }
    113 int main()
    114 {
    115     scanf("%d",&t);
    116     //ans表示测试的第几个样例
    117     int ans=1;
    118     while(t--)
    119     {
    120         s=1;
    121         memset(head,-1,sizeof(head));
    122         scanf("%d %d %d",&n,&m,&p);
    123         //初始化层
    124         init(n,p);
    125         int a,b,c;
    126         //初始化点与层之间的权值
    127         for(int i=1;i<=n;i++)
    128         {
    129             scanf("%d",&a);
    130             add(i,a+n,0);
    131             add(a+2*n,i,0);
    132         }
    133         //初始化点与点之间的权值
    134         for(int i=1;i<=m;i++)
    135         {
    136             scanf("%d %d %d",&a,&b,&c);
    137             add(a,b,c);
    138             add(b,a,c);
    139         }
    140         spfa();
    141         printf("Case #%d: ",ans++);
    142         //判断是否有解
    143         if(dis[n]!=INF)
    144         {
    145             printf("%d
    ",dis[n]);
    146         }
    147         else
    148         {
    149             printf("-1
    ");
    150         }
    151     }
    152 }


  • 相关阅读:
    通过注册表获取计算机相关信息
    GetTickCount()函数
    SystemInfo获取计算机相关信息
    CriticalSection 临界区
    mysql慢查询问题
    mysql show processlist详解
    nginx及php版本号隐藏
    安装psutil模块报错&安装python-devel
    ubuntu ssh重启
    php-fpm配置优化
  • 原文地址:https://www.cnblogs.com/mzchuan/p/11567580.html
Copyright © 2011-2022 走看看