LA 5854 Long Distance Taxi (SPFA 变型) - from lanshui_Yang
来源:互联网 发布:瓜子二手车网站源码 编辑:程序博客网 时间:2024/05/16 07:58
题目大意:直接抽象一下,有多个城市,这些城市之间有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
- 虚拟机VMware Workstation 10.0试用【多图】
- 2618交换机链路聚合配置
- 一定要牢记Debug版本和Release版本的区别
- memcpy实现
- 2618交换机STP配置
- LA 5854 Long Distance Taxi (SPFA 变型) - from lanshui_Yang
- 2618交换机版本升级实验
- 关于将undefined reference to `*'的解决方法
- Java操作MongoDB之CRUD(增删改查)
- Java 多线程使用:线程的挂起与重新唤醒
- 深圳有方科技笔试题(c语言)
- 关于Vmware6.5虚拟机安装vmwaretools以及文件共享的问题
- 3228交换机的基本操作
- poj 2777 Count Color