从起点,终点分别做两次Dijkatra,算出每一点到起点的最短路程d[i]和到终点的最短路程c[i],枚举K条商业线,作为连接最短路的边,看看d[i]+c[j]+W[i][j]是不是更小了。
代码:
#include <iostream> #include <cstdio> #include <cstring> using namespace std; #include <algorithm> #include <queue> #include <vector> #define INF 1000000000 struct edge{ int s,t,cost; edge(){} edge(int s,int t,int c):s(s),t(t),cost(c){} }; vector<edge> EE; vector<int> Ec[505]; int d[505]; int c[505]; int N,S,E,M,K; bool vis[505]; int pd[505]; int pc[505]; void Init(){ EE.clear(); for(int i=1;i<=N;i++){ d[i]=INF; c[i]=INF; Ec[i].clear(); } memset(pc,0,sizeof(pc)); memset(pd,0,sizeof(pd)); } void addedge(int s,int t,int c){ EE.push_back(edge(s,t,c)); Ec[s].push_back(EE.size()-1); } struct HNode{ int d,u; bool operator <(const HNode &obj)const{ return d>obj.d; } }; void dij(int s,int d[],int p[]){ d[s]=0; memset(vis,0,sizeof(vis)); priority_queue<HNode> Q; Q.push(HNode{0,s}); while(!Q.empty()){ HNode cur=Q.top(); Q.pop(); if(vis[cur.u]) continue; vis[cur.u]=1; for(int i=0;i<Ec[cur.u].size();i++){ edge &tmp=EE[Ec[cur.u][i]]; if(d[tmp.t]>d[cur.u]+tmp.cost){ d[tmp.t]=d[cur.u]+tmp.cost; p[tmp.t]=cur.u; Q.push(HNode{d[tmp.t],tmp.t}); } } } } void PrintD(int t){ if(t==S) printf("%d",S); else{ PrintD(pd[t]); printf(" %d",t); } } void PrintC(int t){ printf(" %d",t); if(t==E) return ; PrintC(pc[t]); } int main(){ bool fir=1; while(~scanf("%d%d%d",&N,&S,&E)){ if(fir) fir=0; else printf("\n"); Init(); scanf("%d",&M); for(int i=0;i<M;i++){ int s,e,cc; scanf("%d%d%d",&s,&e,&cc); addedge(s,e,cc); addedge(e,s,cc); } dij(S,d,pd); dij(E,c,pc); int mids=0,midt=0; int Min=d[E]; scanf("%d",&K); for(int i=0;i<K;i++){ int s,e,cost; scanf("%d%d%d",&s,&e,&cost); if(Min>d[s]+c[e]+cost){ Min=d[s]+c[e]+cost; mids=s; midt=e; } if(Min>d[e]+c[s]+cost){ Min=d[e]+c[s]+cost; mids=e; midt=s; } } if(mids==0){ PrintD(E); printf("\n"); printf("Ticket Not Used\n"); printf("%d\n",d[E]); } else { PrintD(mids); PrintC(midt); printf("\n"); printf("%d\n",mids); printf("%d\n",Min); } } return 0; }