最短路问题。
从起点和终点开始各跑一次dijkstra,可以得到起点、终点到任意点的距离。枚举使用的商业线路,找最优解。
破题卡输出,记录前驱和输出什么的仿佛比算法本身还麻烦。
/*by SilverN*/ #include#include #include #include #include #include #include using namespace std; const int mxn=2410; int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } int n,m,k,S,E; struct exp{ int x,y,w; }ex[mxn]; struct edge{ int v,nxt,dis; }e[mxn<<2]; int hd[mxn],mct=0; void add_edge(int u,int v,int d){ e[++mct].v=v;e[mct].nxt=hd[u];e[mct].dis=d;hd[u]=mct; return; } struct node{ int v,d; bool operator < (const node r) const {return d>r.d;} }; priority_queue tp; int pre[mxn],nxt[mxn]; int dis[mxn]; int mdis[mxn]; void Dij1(int st){ while(!tp.empty())tp.pop(); memset(dis,0x3f,sizeof dis); tp.push((node){st,0}); dis[st]=0; while(!tp.empty()){ node tmp=tp.top();tp.pop(); if(tmp.d>dis[tmp.v])continue; int u=tmp.v; for(int i=hd[u];i;i=e[i].nxt){ int v=e[i].v; if(dis[v]>dis[u]+e[i].dis){ dis[v]=dis[u]+e[i].dis; pre[v]=u; tp.push((node){v,dis[v]}); } } } return; } void Dij2(int st){ while(!tp.empty())tp.pop(); memset(dis,0x3f,sizeof dis); tp.push((node){st,0}); dis[st]=0; while(!tp.empty()){ node tmp=tp.top();tp.pop(); if(tmp.d>dis[tmp.v])continue; int u=tmp.v; for(int i=hd[u];i;i=e[i].nxt){ int v=e[i].v; if(dis[v]>dis[u]+e[i].dis){ dis[v]=dis[u]+e[i].dis; nxt[v]=u; tp.push((node){v,dis[v]}); } } } return; } int st[mxn],top=0; void init(){ memset(hd,0,sizeof hd); memset(pre,0,sizeof pre); memset(nxt,0,sizeof nxt); mct=0;top=0; } int main(){ int i,j; bool flag=0; while(scanf("%d%d%d%d",&n,&S,&E,&m)!=EOF){ if(flag){ printf("\n"); } flag=1; init(); int u,v,w; for(i=1;i<=m;i++){ u=read();v=read();w=read(); add_edge(u,v,w); add_edge(v,u,w); } k=read(); for(i=1;i<=k;i++){ ex[i].x=read();ex[i].y=read(); ex[i].w=read(); } Dij1(S); memcpy(mdis,dis,sizeof dis); Dij2(E); int pos1=0,pos2=0,ans=1e9; for(i=1;i<=n;i++){ if(ans>mdis[i]+dis[i]){ ans=mdis[i]+dis[i]; pos1=i; } } for(i=1;i<=k;i++){ int tmp=mdis[ex[i].x]+dis[ex[i].y]+ex[i].w; if(ans>tmp){ ans=tmp;pos1=ex[i].x;pos2=ex[i].y; } tmp=mdis[ex[i].y]+dis[ex[i].x]+ex[i].w; if(ans>tmp){ ans=tmp;pos1=ex[i].y;pos2=ex[i].x; } } if(pos1 && !pos2){ // printf("Test1\n"); int tmp=pos1; while(pre[pos1]){ pos1=pre[pos1]; st[++top]=pos1; } while(top) printf("%d ",st[top--]); pos1=tmp; do{ printf("%d",pos1); if(nxt[pos1])printf(" "); pos1=nxt[pos1]; }while(pos1); printf("\nTicket Not Used\n"); } else{ if(pos1 && pos2){ int tmp=pos1; while(pre[pos1]){ pos1=pre[pos1]; st[++top]=pos1; } while(top) printf("%d ",st[top--]); pos1=tmp; printf("%d ",pos1); // pos2=nxt[pos2]; while(pos2){ printf("%d",pos2); if(nxt[pos2])printf(" "); pos2=nxt[pos2]; } printf("\n%d\n",pos1); } } printf("%d\n",ans); } return 0; }