LA 5854 Long Distance Taxi (SPFA 变型) - from lanshui_Yang
来源:互联网 发布:望舒剑淘宝 编辑:程序博客网 时间:2024/05/17 05:06
LA 5854 Long Distance Taxi (SPFA 变型) - from lanshui_Yang
分类: 图论2013-09-27 20:36 102人阅读 评论(0) 收藏 举报
变型的SPFA
题目大意:直接抽象一下,有多个城市,这些城市之间有n条无向边,有一个旅行家(假设叫Mike),他有一辆摩托车,摩托车的邮箱大小为cap,其耗油量是 10千米/每升油,给定一个起点、一个终点和cap的值以及有加油站的城市 (Mike 可以在这些城市加满油),让你判断Mike是否可以从起点到达终点,如果可以,就求出路程的最小值,否则,就输出"-1"。
解题思路:这道题是一道变型的最短路问题,比普通的最短路难了许多。一般的最短路问题可以用SPFA解决,这道题也可以,但有些变化,这里队列中的对象是二维的,一个是顶点的编号,一个是摩托车还能走的路程。
请看代码:
- #include<iostream>
- #include<cstring>
- #include<string>
- #include<cmath>
- #include<cstdio>
- #include<vector>
- #include<set>
- #include<queue>
- #include<map>
- #include<algorithm>
- #define mem(a , b ) memset(a , b , sizeof(a))
- using namespace std ;
- const int MAXN = 3006 ;
- const int INF = 0x7fffffff ;
- struct Edge
- {
- int adj ;
- int d ;
- int next ;
- }E[MAXN * 2] ;
- int head[MAXN * 2] ;
- int ed ;
- struct Q
- {
- int Node ;
- int C ;
- };
- int n , m , cap ;
- string s1 , s2 ;
- int st , e ;
- map<string , int> mp ;
- int cnt ;
- bool inq[MAXN * 2][2006] ;
- int dis[MAXN * 2][2006] ;
- bool P[MAXN * 2] ; // 判断城市是否有加油站
- char ss1[100] , ss2[100] ;
- void chu()
- {
- mp.clear() ;
- cnt = 0 ;
- ed = 0 ;
- mem(head , 0) ;
- mem(dis , 0) ;
- mem(P , 0) ;
- mem(inq , 0) ;
- }
- void init()
- {
- chu() ;
- scanf("%s%s" , ss1 , ss2) ;
- s1 = string(ss1) ;
- s2 = string(ss2) ;
- if(mp.find(s1) == mp.end())
- {
- mp[s1] = ++ cnt ;
- }
- if(mp.find(s2) == mp.end())
- {
- mp[s2] = ++ cnt ;
- }
- st = mp[s1] ;
- e = mp[s2] ;
- cap *= 10 ;
- int i ;
- int td ;
- int ta , tb ;
- for(i = 0 ; i < n ; i ++)
- {
- scanf("%s%s" , ss1 , ss2) ;
- s1 = string(ss1) ;
- s2 = string(ss2) ;
- scanf("%d" , &td) ;
- if(!mp[s1])
- {
- mp[s1] = ++ cnt ;
- }
- if(!mp[s2])
- {
- mp[s2] = ++ cnt ;
- }
- ta = mp[s1] ;
- tb = mp[s2] ;
- if(td <= cap) // 建图
- {
- ++ ed ;
- E[ed].adj = tb ;
- E[ed].d = td ;
- E[ed].next = head[ta] ;
- head[ta] = ed ;
- ++ ed ;
- E[ed].adj = ta ;
- E[ed].d = td ;
- E[ed].next = head[tb] ;
- head[tb] = ed ;
- }
- }
- for(i = 0 ; i < m ; i ++)
- {
- scanf("%s" , ss1) ;
- s1 = string(ss1) ;
- if(!mp[s1])
- {
- mp[s1] = ++ cnt ;
- }
- int t = mp[s1] ;
- P[t] = true ;
- }
- }
- queue<Q> q ;
- void spfa(Q u)
- {
- while (!q.empty()) q.pop() ;
- q.push(u) ;
- inq[u.Node][u.C] = true ;
- while (!q.empty())
- {
- Q v = q.front() ;
- q.pop() ;
- inq[v.Node][v.C] = false ;
- int i ;
- i = head[v.Node] ;
- while (i != 0)
- {
- Edge tv = E[i] ;
- int vn = tv.adj ;
- int vd = tv.d ;
- int se = v.C - vd ;
- if(P[vn]) // 注意此处
- {
- se = cap ;
- }
- if(v.C - vd >= 0 && dis[v.Node][v.C] + vd < dis[vn][se] )
- {
- dis[vn][se] = dis[v.Node][v.C] + vd ;
- if(!inq[vn][se])
- {
- inq[vn][se] = true ;
- Q tmp ;
- tmp.Node = vn ;
- tmp.C = se ;
- q.push(tmp) ;
- }
- }
- i = E[i].next ;
- }
- }
- }
- void solve()
- {
- int i , j ;
- for(i = 1 ; i <= cnt ; i ++)
- {
- for(j = 0 ; j <= cap ; j ++)
- dis[i][j] = INF ;
- }
- dis[st][cap] = 0 ;
- Q Stmp ;
- Stmp.Node = st ;
- Stmp.C = cap ;
- spfa(Stmp) ;
- int MIN = INF ;
- for(i = 0 ; i <= cap ; i ++)
- {
- MIN = min(MIN , dis[e][i]) ;
- }
- if(MIN == INF)
- puts("-1") ;
- else
- printf("%d\n" , MIN) ;
- }
- int main()
- {
- while (scanf("%d%d%d" , &n , &m , &cap) != EOF)
- {
- if(n == 0 && m == 0 && cap == 0)
- break ;
- init() ;
- solve() ;
- }
- return 0 ;
- }
- LA 5854 Long Distance Taxi (SPFA 变型) - from lanshui_Yang
- LA 5854 Long Distance Taxi (SPFA 变型) - from lanshui_Yang
- aizu 1318 Long Distance Taxi
- LA 3211 Now or later (2 - SAT) - from lanshui_Yang
- POJ 1135 Domino Effect (spfa + 枚举)- from lanshui_Yang
- 1062 昂贵的聘礼 (spfa + 等级枚举) - from lanshui_Yang
- Aizu 1318 Long Distance Taxi 最短路
- POJ 2449 Remmarguts' Date (SPFA + A星算法) - from lanshui_Yang
- LA 5966 Blade and Sword (双向bfs + 想法) - from lanshui_Yang
- HDU 2255(KM) - from lanshui_Yang
- POJ Chores - from lanshui_Yang
- POJ 3104 Drying (神题 啊 ~) -- from lanshui_Yang
- POJ 1273 Drainage Ditches(EK) - from lanshui_Yang
- POJ 3678 Katu Puzzle(2 - SAT) - from lanshui_Yang
- POJ 1251 Jungle Roads(最小生成树水题) - from lanshui_Yang
- POJ 2195 Going Home(KM)- from lanshui_Yang
- POJ 2400 Supervisor, Supervisee (KM + 回溯) - from lanshui_Yang
- POJ 1274 The Perfect Stall(二分匹配)- from lanshui_Yang
- java常用类
- 套接字
- 自定义滚动条
- poj3083 Children of the Candy Corn
- xdebug参数配置详解
- LA 5854 Long Distance Taxi (SPFA 变型) - from lanshui_Yang
- 算法之斐波那契数列
- 学习数据结构的作用
- ASP.NET 母版页示例代码
- 【笔试】TX——web前端
- MFC画图
- 字符编码笔记:ASCII,Unicode和UTF-8
- KMP
- 给定一个数字,求比它大的最小的非重复数字