zoukankan      html  css  js  c++  java
  • hdu4396 多状态spfa

    题意:
          给你一个图,让你送起点走到终点,至少经过k条边,问你最短路径是多少....


    思路:

          把每个点拆成50点,记为dis[i][j] (i 1---50 ,j 1---n);代表走到第j个点做过i条边时的最短距离,因为做多五十条边,如果走的过程中,边数大于50直接等于50,因为大于50的时候就没有必要走"回头路"了...然后跑完spfa后在dis[i][t](i =  k---50)中取一个最小的输出来,就行了...


    #include<stdio.h>
    #include<string.h>
    #include<queue>
    
    #define N_node 5000 + 100
    #define N_edge 200000 + 1000
    #define inf 100000000
    
    using namespace std;
    
    typedef struct
    {
       int to ,next ,cost;
    }STAR;
    
    typedef struct
    {
       int x ,t;
    }NODE;
    
    int s_x[55][N_node] ,n ,m ,s ,t;
    int mark[55][N_node];
    int list[N_node] ,tot;
    NODE xin ,tou;
    STAR E[N_edge];
    
    
    void add(int a ,int b ,int c)
    {
       E[++tot].to = b;
       E[tot].cost = c;
       E[tot].next = list[a];
       list[a] = tot;
    }
    
    
    
    void SPFA()
    {
       for(int i = 0 ;i <= 52 ;i ++)
       for(int j = 1 ;j <= n ;j ++)
       s_x[i][j] = inf;
      // printf("%d %d
    " ,s_x[1][3] ,s_x[1][2]);
       s_x[0][s] = 0;
       xin.x = s;
       xin.t = 0;
       queue<NODE>q;
       q.push(xin);
       memset(mark ,0 ,sizeof(mark));
       mark[0][s] = 1;
       while(!q.empty())
       {
          tou = q.front();
          q.pop();
          mark[tou.t][tou.x] = 0;
          for(int k = list[tou.x] ;k ;k = E[k].next)
          {
             xin.x = E[k].to;
             xin.t = tou.t + 1;
             if(xin.t > 50) xin.t = 50;
             //printf("%d %d %d %d
    " ,s_x[xin.t][xin.x] ,s_x[tou.t][tou.x] + E[k].cost ,xin.t ,xin.x);
             if(s_x[xin.t][xin.x] > s_x[tou.t][tou.x] + E[k].cost)
             {
                s_x[xin.t][xin.x] = s_x[tou.t][tou.x] + E[k].cost;
                
                if(!mark[xin.t][xin.x])
                {
                   mark[xin.t][xin.x] = 1;
                   q.push(xin);
                }
             }
          }
       }
    }
    
    int main ()
    {
       int m ,a ,b ,c ,k ,i;
       while(~scanf("%d %d" ,&n ,&m))
       {
          memset(list ,0 ,sizeof(list));
          tot = 1;
          for(i = 1 ;i <= m ;i ++)
          {
             scanf("%d %d %d" ,&a ,&b ,&c);
             add(a ,b ,c);
             add(b ,a ,c);
          }
          
          scanf("%d %d %d" ,&s ,&t ,&k);
          SPFA();
          int ans = inf;
          k = (k + 9)/10;
          for(i = k ;i <= 50 ;i ++)
          if(ans > s_x[i][t])
          ans = s_x[i][t];
          if(ans == inf) ans = -1;
          printf("%d
    " ,ans);
       }
       return 0;
    }
       
       
      
    

  • 相关阅读:
    简易高重用的jdbcutils工具封装实现类以及简易连接池实现
    http header 具体解释
    zoj 3888 Twelves Monkeys 二分+线段树维护次小值
    hyperLink的定制
    document.body.clientHeight的取值
    在循环中创建网页元素的问题
    mongo db 启动停止
    myeclipse 2014破解
    weblogic 集群部署时上传jsp不更新问题
    Spring classPath:用法
  • 原文地址:https://www.cnblogs.com/csnd/p/12063262.html
Copyright © 2011-2022 走看看