LA 5854 Long Distance Taxi (SPFA 变型) - from lanshui_Yang

来源:互联网 发布:望舒剑淘宝 编辑:程序博客网 时间:2024/05/17 05:06
 

LA 5854 Long Distance Taxi (SPFA 变型) - from lanshui_Yang

分类: 图论 102人阅读 评论(0) 收藏 举报
变型的SPFA

      题目大意:直接抽象一下,有多个城市,这些城市之间有n条无向边,有一个旅行家(假设叫Mike),他有一辆摩托车,摩托车的邮箱大小为cap,其耗油量是 10千米/每升油,给定一个起点、一个终点和cap的值以及有加油站的城市 (Mike 可以在这些城市加满油),让你判断Mike是否可以从起点到达终点,如果可以,就求出路程的最小值,否则,就输出"-1"。

      解题思路:这道题是一道变型的最短路问题,比普通的最短路难了许多。一般的最短路问题可以用SPFA解决,这道题也可以,但有些变化,这里队列中的对象是二维的,一个是顶点的编号,一个是摩托车还能走的路程。

      请看代码:

[cpp] view plaincopy
  1. #include<iostream>  
  2. #include<cstring>  
  3. #include<string>  
  4. #include<cmath>  
  5. #include<cstdio>  
  6. #include<vector>  
  7. #include<set>  
  8. #include<queue>  
  9. #include<map>  
  10. #include<algorithm>  
  11. #define mem(a , b ) memset(a , b , sizeof(a))  
  12. using namespace std ;  
  13. const int MAXN = 3006 ;  
  14. const int INF = 0x7fffffff ;  
  15. struct Edge  
  16. {  
  17.     int adj ;  
  18.     int d ;  
  19.     int next ;  
  20. }E[MAXN * 2] ;  
  21. int head[MAXN * 2] ;  
  22. int ed ;  
  23. struct Q  
  24. {  
  25.     int Node ;  
  26.     int C ;  
  27. };  
  28. int n , m , cap ;  
  29. string s1 , s2 ;  
  30. int st , e ;  
  31. map<string , int> mp ;  
  32. int cnt ;  
  33. bool inq[MAXN * 2][2006] ;  
  34. int dis[MAXN * 2][2006] ;  
  35. bool P[MAXN * 2] ; // 判断城市是否有加油站  
  36. char ss1[100] , ss2[100] ;  
  37. void chu()  
  38. {  
  39.     mp.clear() ;  
  40.     cnt = 0 ;  
  41.     ed = 0 ;  
  42.     mem(head , 0) ;  
  43.     mem(dis , 0) ;  
  44.     mem(P , 0) ;  
  45.     mem(inq , 0) ;  
  46. }  
  47. void init()  
  48. {  
  49.     chu() ;  
  50.     scanf("%s%s" , ss1 , ss2) ;  
  51.     s1 = string(ss1) ;  
  52.     s2 = string(ss2) ;  
  53.     if(mp.find(s1) == mp.end())  
  54.     {  
  55.         mp[s1] = ++ cnt ;  
  56.     }  
  57.     if(mp.find(s2) == mp.end())  
  58.     {  
  59.         mp[s2] = ++ cnt ;  
  60.     }  
  61.     st = mp[s1] ;  
  62.     e = mp[s2] ;  
  63.     cap *= 10 ;  
  64.     int i ;  
  65.     int td ;  
  66.     int ta , tb ;  
  67.     for(i = 0 ; i < n ; i ++)  
  68.     {  
  69.         scanf("%s%s" , ss1 , ss2) ;  
  70.         s1 = string(ss1) ;  
  71.         s2 = string(ss2) ;  
  72.         scanf("%d" , &td) ;  
  73.         if(!mp[s1])  
  74.         {  
  75.             mp[s1] = ++ cnt ;  
  76.         }  
  77.         if(!mp[s2])  
  78.         {  
  79.             mp[s2] = ++ cnt ;  
  80.         }  
  81.         ta = mp[s1] ;  
  82.         tb = mp[s2] ;  
  83.         if(td <= cap)  // 建图  
  84.         {  
  85.             ++ ed ;  
  86.             E[ed].adj = tb ;  
  87.             E[ed].d = td ;  
  88.             E[ed].next = head[ta] ;  
  89.             head[ta] = ed ;  
  90.   
  91.             ++ ed ;  
  92.             E[ed].adj = ta ;  
  93.             E[ed].d = td ;  
  94.             E[ed].next = head[tb] ;  
  95.             head[tb] = ed ;  
  96.         }  
  97.     }  
  98.     for(i = 0 ; i < m ; i ++)  
  99.     {  
  100.         scanf("%s" , ss1) ;  
  101.         s1 = string(ss1) ;  
  102.         if(!mp[s1])  
  103.         {  
  104.             mp[s1] = ++ cnt ;  
  105.         }  
  106.         int t = mp[s1] ;  
  107.         P[t] = true ;  
  108.     }  
  109. }  
  110. queue<Q> q ;  
  111. void spfa(Q u)  
  112. {  
  113.     while (!q.empty()) q.pop() ;  
  114.     q.push(u) ;  
  115.     inq[u.Node][u.C] = true ;  
  116.     while (!q.empty())  
  117.     {  
  118.         Q v = q.front() ;  
  119.         q.pop() ;  
  120.         inq[v.Node][v.C] = false ;  
  121.         int i ;  
  122.         i = head[v.Node] ;  
  123.         while (i != 0)  
  124.         {  
  125.             Edge tv = E[i] ;  
  126.             int vn = tv.adj ;  
  127.             int vd = tv.d ;  
  128.             int se = v.C - vd ;  
  129.             if(P[vn]) // 注意此处  
  130.             {  
  131.                 se = cap ;  
  132.             }  
  133.             if(v.C - vd >= 0 && dis[v.Node][v.C] + vd < dis[vn][se] )  
  134.             {  
  135.   
  136.                 dis[vn][se] = dis[v.Node][v.C] + vd  ;  
  137.                 if(!inq[vn][se])  
  138.                 {  
  139.                     inq[vn][se] = true ;  
  140.                     Q tmp ;  
  141.                     tmp.Node = vn ;  
  142.                     tmp.C = se ;  
  143.                     q.push(tmp) ;  
  144.                 }  
  145.             }  
  146.             i = E[i].next ;  
  147.         }  
  148.     }  
  149. }  
  150. void solve()  
  151. {  
  152.     int i , j ;  
  153.     for(i = 1 ; i <= cnt ; i ++)  
  154.     {  
  155.         for(j = 0 ; j <= cap ; j ++)  
  156.             dis[i][j] = INF ;  
  157.     }  
  158.     dis[st][cap] = 0 ;  
  159.     Q Stmp ;  
  160.     Stmp.Node = st ;  
  161.     Stmp.C = cap ;  
  162.     spfa(Stmp) ;  
  163.     int MIN = INF ;  
  164.     for(i = 0 ; i <= cap ; i ++)  
  165.     {  
  166.         MIN = min(MIN , dis[e][i]) ;  
  167.     }  
  168.     if(MIN == INF)  
  169.         puts("-1") ;  
  170.     else  
  171.         printf("%d\n" , MIN) ;  
  172. }  
  173. int main()  
  174. {  
  175.     while (scanf("%d%d%d" , &n , &m , &cap) != EOF)  
  176.     {  
  177.         if(n == 0 && m == 0 && cap == 0)  
  178.             break ;  
  179.         init() ;  
  180.         solve() ;  
  181.     }  
  182.     return 0 ;  
  183. }  
原创粉丝点击