您的位置:首页 > 产品设计 > UI/UE

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

2013-10-04 00:39 363 查看


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解决,这道题也可以,但有些变化,这里队列中的对象是二维的,一个是顶点的编号,一个是摩托车还能走的路程。

请看代码:

[cpp] view
plaincopy

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

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: