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

    题意:n个点,给定每个点的层次,可以从当前层任何节点到达下一个层任何节点,x->x+1 ,x+1->x 花费c,还有一些额外的边可以直接走。求1-n的最短路

    做法:想到了如果直接扩展所有节点的话肯定超时,所以找出关键点扩展就好了,什么关键点,叫着好听而已,就是那些必要的点而已,包括给出的边的点,还有起点终点,每层至少保证一个点。然后spfa迭代,按额外的边迭代,往上一层迭代,往下一层迭代。

    刚开始没能保证n点加进去,一直wa

    #define maxn 100005
    
    const int inf = 0x3fffffff;
    
    struct node
    {
      int v,next;
      int w ;
    };
    node e[maxn * 2 ];
    int cnt ;
    int head[maxn];
    vector<int> p[maxn],p1[maxn];
    int vis[maxn];
    int lev[maxn];
    int n,m,c;
    int _mx;
    int dis[maxn];
    void init()
    {
      memset(head,-1,sizeof(head));
      cnt = 0 ;
    }
    void add(int u , int v , int w )
    {
      //printf("add %d %d %d 
    ",u,v,w);
      e[cnt].v = v ;
      e[cnt].w = w ;
      e[cnt].next = head[u] ;
      head[u] = cnt ++ ;
      e[cnt].v = u;
      e[cnt].w = w;
      e[cnt].next = head[v];
      head[v] = cnt ++ ;
      return ;
    }
    queue<int> q;
    void spfa()
    {
      while(!q.empty()) q.pop();
      for(int i = 0; i <= n ; i ++ )
      {
        vis[i] = 0 ;
        dis[i] = inf;
      }
      vis[1] = 1 ;
      dis[1] = 0 ;
      q.push(1);
      int u , v , ll ,sz ;
      while(!q.empty())
      {
        u = q.front();
       // printf("u = %d lev[%d] = %d
    ",u,u,lev[u]);
       // printf("dis[u] = %d
    ",dis[u]);
        q.pop();
        for(int i = head[u]; i != -1 ; i = e[i].next)
        {
          //printf("e[i].w = %d
    ",e[i].w);
          v = e[i].v;
          if(dis[u] + e[i].w < dis[v] )
          {
            dis[v] = dis[u] + e[i].w ;
           // printf("dis[%d] = %d
    ",v,dis[v]);
            if(!vis[v] )
            {
              vis[v] = 1 ;
              q.push(v);
            }
          }
        }
        ll = lev[u];
        if(ll != 1 )
        {
          sz = p1[ll-1].size();
          for(int i = 0 ; i < sz; i ++ )
          {
            v = p1[ll-1][i];
            if(dis[u] + c < dis[v] )
            {
              dis[v] = dis[u] + c ;
              if(!vis[v] )
              {
                vis[v] = 1 ;
                q.push(v);
              }
            }
          }
        }
        if(ll != _mx)
        {
          sz = p1[ll+1].size();
          for(int i = 0 ; i < sz; i ++ )
          {
            v = p1[ll+1][i];
            if(dis[u] + c < dis[v] )
            {
              dis[v] = dis[u] + c ;
             // printf("dis[%d] = %d
    ",v,dis[v]);
              if(!vis[v] )
              {
                vis[v] = 1 ;
                q.push(v);
              }
            }
          }
        }
        vis[u] = 0;
      }
    
    }
    
    int main()
    {
      int cas;
      int cast = 0 ;
      scanf("%d",&cas);
      while(cas -- )
      {
        scanf("%d%d%d",&n,&m,&c);
       // printf("c = %d
    ",c);
        memset(lev, 0 , sizeof(lev));
        for(int i = 1 ; i <= n; i ++ ) p[i].clear(),p1[i].clear();
        memset(vis,0,sizeof(vis));
        _mx = 0 ;
        for(int i = 1 ; i <= n ; i++ )
        {
          scanf("%d",&lev[i]);
          _mx = max(_mx , lev[i]);
          p[lev[i]].push_back(i);
          if(p1[lev[i]].size() <= 3 )
          {
            p1[lev[i]].push_back(i);
            vis[i] = 1 ;
          }
        }
        init();
        int u,v,w;
        for(int i = 0; i < m ; i ++ )
        {
          scanf("%d%d%d",&u,&v,&w);
          add(u,v,w);
          if(!vis[u])
          {
            p1[lev[u]].push_back(u);
            vis[u] = 1 ;
          }
          if(!vis[v] )
          {
            p1[lev[v]].push_back(v);
            vis[v] = 1 ;
          }
        }
        if(n == 0 )
        {
          printf("Case #%d: -1
    ",++cast);
          continue;
        }
        else if(n == 1 )
        {
          printf("Case #%d: 0
    ",++cast);
          continue;
        }
        if(!vis[1])p1[lev[1]].push_back(1);
        if(!vis[n])p1[lev[n]].push_back(n);
       // for(int i = 1 ; i <= _mx; i ++ )
        //{
        //  for(int j = 0 ; j < p1[i].size(); j ++ )
       //   {
        //    printf("%d ",p1[i][j]);
        //  }
       //   printf("
    ");
       // }
        spfa();
        printf("Case #%d: ",++cast);
        if(dis[n] >= inf)
          printf("-1
    ");
        else printf("%d
    ",dis[n]);
      }
      return 0;
    }
    View Code
  • 相关阅读:
    hibernate 主键利用uuid生成
    Jquery ui widget开发
    完美解决IE6不支持position:fixed的bug
    rose pipe–一次对http技术的伟大革新实现(54chen乱弹版)
    关于JBoss的Log4j的输出问题
    《rose portal & pipe技术介绍》之《变革:结构&范围》
    click() 方法和mousedown
    BigPipe具体实现细节
    获取汉字首字母,拼音,可实现拼音字母搜索npm jspinyin
    时间戳显示格式为几天前、几分钟前、几秒前vue过滤器
  • 原文地址:https://www.cnblogs.com/jh818012/p/3315545.html
Copyright © 2011-2022 走看看