这道题和其他最短路问题相比多了一个互相转换的关系,其实也没什么区别,只是做一下多维的情况,将每个城市的四个交通工具设为4个点。
也就是说普通最短路一个点代表一个城市,而现在是每个城市的四种交通工具都代表一个点,这样其实只是需要用map映射一下关系就行
另外的就是,因为起点和终点都有多种可能,也就是多源的最短路。常用的做法就是设一个额外的起点和终点,就能转化过来了,当然,直接放四个点进去也行的
之后就是普通最短路的做法了
#include<iostream> #include<cstring> #include<cstdio> #include<map> #include<algorithm> #include<queue> #include<set> #define ull unsigned long long using namespace std; typedef long long ll; typedef pair<int,int> pll; typedef pair<int,pair<int,int> > plll; const int N=1e5+10; const int inf=0x3f3f3f3f; map<string,int> m1[N],id; vector<pll> g[N]; int st[N]; int d[N]; void dij(){ priority_queue<pll,vector<pll>,greater<pll> > q; memset(d,0x3f,sizeof d); memset(st,0,sizeof st); d[0]=0; q.push(pll{0,0}); while(q.size()){ int t=q.top().first; int u=q.top().second; q.pop(); if(st[u]) continue; st[u]=1; int i; for(i=0;i<g[u].size();i++){ int cost=g[u][i].second; int j=g[u][i].first; if(d[j]>d[u]+cost){ d[j]=d[u]+cost; q.push(pll{d[j],j}); } } } } int main(){ int t; cin>>t; id["BOAT"]=0;id["RAIL"]=1;id["AIR"]=2;id["TRUCK"]=3; while(t--){ int n; cin>>n; int i; int tot=0; for(int i=0;i<4;i++)m1[i].clear(); for(int i=0;i<=4*n+1;i++)g[i].clear(); for(i=1;i<=n;i++){ string s;int c; cin>>s>>c; int j,k; for(j=0;j<4;j++){ m1[j][s]=++tot; } for(j=0;j<4;j++){ for(k=0;k<4;k++){ if(j!=k){ g[m1[j][s]].push_back(pll{m1[k][s],c}); } } } } int q; cin>>q; while(q--){ string a,b,c; int d; cin>>a>>b>>c>>d; int tmp=id[c]; g[m1[tmp][a]].push_back(pll{m1[tmp][b],d}); g[m1[tmp][b]].push_back(pll{m1[tmp][a],d}); } string st,ed; cin>>st>>ed; for(i=0;i<4;i++){ g[0].push_back(pll{m1[i][st],0}); } for(i=0;i<4;i++){ g[m1[i][ed]].push_back(pll{4*n+1,0}); } dij(); cout<<d[4*n+1]<<endl; } }