給定一個起點、一個終點和cap的值以及有加油站的城市 (Mike 可以在這些城市加滿油),讓你判斷Mike是否可以從起點到達終點,如果可以,就求出路程的最小值,否則,就輸出"-1"。
#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 ;}