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;
}
   
   
  

原文地址:https://www.cnblogs.com/csnd/p/12063263.html