UVALive - 5854 最短路
求出加油站两两之间的最短路,判断下即可
#include<iostream> #include<cstring> #include <cstdio> #include<string> #include<queue> #include<vector> #include<map> #include <set> #include<ctime> #include<cmath> #include <cstdlib> #include<algorithm> #include <iomanip> using namespace std; const int N = 10000; const int INF = ((1<<30)-1); int oil[N]; char str1[100],str2[100]; int dis[N],q[N],n; bool vis[N]; void spfa(int s,vector< pair<int,int> > list[N]){ for(int i=0;i<N;i++) dis[i]=INF; memset(vis,0,sizeof(vis)); int head=0,tail=0; q[tail++]=s; dis[s]=0,vis[s]=true; while(head!=tail){ int u=q[head]; for(int i=0;i<list[u].size();i++){ int v=list[u][i].first,w=list[u][i].second; if(dis[v]>dis[u]+w){ dis[v]=dis[u]+w; if(!vis[v]){ vis[v]=true; q[tail++]=v; if(tail==N-10) tail=0; } } } vis[u]=false; head++; if(head==N-10) head=0; } } vector< pair<int,int> > G[N],g[N]; int main(){ int n,m,k; while(scanf("%d%d%d",&n,&m,&k)!=EOF){ k=k*10; for(int i=0;i<=2*n;i++) G[i].clear(); for(int i=0;i<=2*n;i++) g[i].clear(); if(!n&&!m&&!k) return 0; map<string,int> mpp; int src=1,des=2,cnt=3; scanf("%s%s",str1,str2); mpp[str1]=src; mpp[str2]=des; for(int i=0;i<n;i++){ int u,v,w; scanf("%s%s%d",str1,str2,&w); if(w>k) continue; if(!mpp[str1]) mpp[str1]=cnt++; if(!mpp[str2]) mpp[str2]=cnt++; u=mpp[str1],v=mpp[str2]; G[u].push_back(make_pair(v,w)); G[v].push_back(make_pair(u,w)); } int tail=0; for(int i=0;i<m;i++){ scanf("%s",str1); oil[tail++]=mpp[str1]; } oil[tail++]=src; oil[tail++]=des; for(int i=0;i<tail;i++){ int u=oil[i]; spfa(u,G); for(int j=0;j<i;j++){ int v=oil[j]; if(dis[v]>k) { g[u].push_back(make_pair(v,INF)); g[v].push_back(make_pair(u,INF)); } else{ g[u].push_back(make_pair(v,dis[v])); g[v].push_back(make_pair(u,dis[v])); } } } spfa(src,g); int ans=dis[des]; if(ans>=INF||ans==-1) printf("-1\n"); else printf("%d\n",ans); } }