zoukankan      html  css  js  c++  java
  • HDU 4725 The Shortest Path in Nya Graph (最短路 )

    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 <= 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.
    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
     
    分析:
    本题的坑点在于建图的时候边数太多,因为每x层与x+1层中的每一个点都相互连接,这样就有 Nx^N(x+1) 条边,sum(Ni)为10^5,暴力建图肯定会爆的
    建图的时候,每一层增加一个“层点”作为中介,然后层点与层点建边,层点与在该层上的点建边(边长为0),点与相邻层点建边(边长为c)。
    最后增加的边,点与点建边。
    在赛场上怂了,看见10^5没敢多建边,只想着如何在层之间建边了。。。对时间复杂度与时间限制的把握还是不好,以后要记住常用算法的复杂度,还要学习如何准确分析时间复杂度
    代码:
      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <queue>
      5 #include <vector>
      6 #define maxn 200005
      7 #define INF 0x3f3f3f3f
      8 using namespace std;
      9 
     10 int n,m,c,ans,cnt;
     11 bool vis[maxn],vv[maxn];
     12 int dist[maxn],pp[maxn],lay[maxn];
     13 struct Node
     14 {
     15     int v,w;
     16     int next;
     17 } edge[20*maxn];
     18 queue<int>q;
     19 
     20 void init()
     21 {
     22     memset(pp,0,sizeof(pp));
     23     memset(vv,0,sizeof(vv));
     24     memset(dist,0x3f,sizeof(dist));
     25 }
     26 void addedge(int u,int v,int w)
     27 {
     28     cnt++;
     29     edge[cnt].v=v;
     30     edge[cnt].w=w;
     31     edge[cnt].next=pp[u];
     32     pp[u]=cnt;
     33 }
     34 void SPFA()
     35 {
     36     int i,j,u,v,w;
     37     memset(vis,0,sizeof(vis));
     38     while(!q.empty()) q.pop();
     39     dist[1]=0;
     40     vis[1]=1;
     41     q.push(1);
     42     while(!q.empty())
     43     {
     44         u=q.front();
     45         q.pop();
     46         vis[u]=0;
     47         for(i=pp[u]; i; i=edge[i].next)
     48         {
     49             v=edge[i].v;
     50             w=edge[i].w;
     51             if(dist[v]>dist[u]+w)
     52             {
     53                 dist[v]=dist[u]+w;
     54                 if(!vis[v])
     55                 {
     56                     vis[v]=1;
     57                     q.push(v);
     58                 }
     59             }
     60         }
     61     }
     62 }
     63 int main()
     64 {
     65     int i,j,t,u,v,w,test=0;
     66     scanf("%d",&t);
     67     while(t--)
     68     {
     69         scanf("%d%d%d",&n,&m,&c);
     70         init();
     71         cnt=0;
     72         for(i=1; i<=n; i++)
     73         {
     74             scanf("%d",&u);
     75             lay[i]=u;
     76             vv[u]=1;
     77         }
     78         for(i=1; i<n; i++)
     79         {
     80             if(vv[i]&&vv[i+1])  // 两层都出现过点相邻层才建边
     81             {
     82                 addedge(n+i,n+i+1,c);
     83                 addedge(n+i+1,n+i,c);
     84             }
     85         }
     86         for(i=1; i<=n; i++)     // 层到点建边  点到相邻层建边
     87         {
     88             addedge(n+lay[i],i,0);
     89             if(lay[i]>1) addedge(i,n+lay[i]-1,c);
     90             if(lay[i]<n) addedge(i,n+lay[i]+1,c);
     91         }
     92         for(i=1; i<=m; i++)     // 点到点建边
     93         {
     94             scanf("%d%d%d",&u,&v,&w);
     95             addedge(u,v,w);
     96             addedge(v,u,w);
     97         }
     98         SPFA();
     99         printf("Case #%d: ",++test);
    100         ans=dist[n];
    101         if(ans<INF) printf("%d
    ",ans);
    102         else printf("-1
    ");
    103     }
    104     return 0;
    105 }
    View Code
  • 相关阅读:
    Hadoopif.for.while 语句
    完全分布模式的四大模块设置
    语法糖定义
    Karaf 依赖equinox and felix,karaf 本Apache的很多项目作为基础框架
    Karaf 基于 osgi
    MEF(Managed Extensibility Framework) 微软平台插件化开发
    析构函数,构造函数
    C#和ASP.Net面试题目集锦
    论C# java的基本类型
    Boolean.parseBoolean("true") 和 Boolean.getBoolean("true");的区别及用法
  • 原文地址:https://www.cnblogs.com/liuzhanshan/p/6783405.html
Copyright © 2011-2022 走看看