訓練指南 UVA - 11374(最短路Dijkstra + 記錄路徑 + 模板)
阿新 • • 發佈:2019-02-02
edge n-1 code ase 最短 ios 就是 swap gets
layout: post
title: 訓練指南 UVA - 11374(最短路Dijkstra + 記錄路徑 + 模板)
author: "luowentaoaa"
catalog: true
mathjax: true
tags:
- 最短路
- Dijkstra
- 圖論
- 訓練指南
Airport Express
UVA - 11374
題意
機場快線有經濟線和商業線,現在分別給出經濟線和商業線的的路線,現在只能坐一站商業線,其他坐經濟線,問從起點到終點的最短用時是多少,還有路線是怎樣的;
題解
預處理出起點到所有站的最短距離和終點到所有站的最短距離,枚舉要坐的那趟商業線,然後裏面最小的就是答案了;
#include<bits/stdc++.h> using namespace std; typedef long long ll; const ll mod=998244353; const int maxn=550; const ll inf=0x3f3f3f3f3f3f3f3fLL; struct Edge{ int from,to,dist; }; struct HeapNode{ int d,u; bool operator <(const HeapNode& rhs)const{ return d>rhs.d; } }; struct Dijkstra{ int n,m; //點數和邊數 點編號0~N-1 vector<Edge>edges; vector<int>G[maxn]; bool done[maxn]; int d[maxn]; int p[maxn]; void init(int n){ this->n=n; for(int i=0;i<n;i++)G[i].clear(); edges.clear(); } void AddEdge(int from,int to,int dist){ edges.push_back((Edge){from,to,dist}); m=edges.size(); G[from].push_back(m-1); } void dijkstra(int s){ priority_queue<HeapNode>Q; for(int i=0;i<n;i++)d[i]=inf; d[s]=0; memset(done,0,sizeof(done)); Q.push((HeapNode){0,s}); while(!Q.empty()){ HeapNode x=Q.top();Q.pop(); int u=x.u; if(done[u])continue; done[u]=true; for(int i=0;i<G[u].size();i++){ Edge& e=edges[G[u][i]]; if(d[e.to]>d[u]+e.dist){ d[e.to]=d[u]+e.dist; p[e.to]=G[u][i]; Q.push((HeapNode){d[e.to],e.to}); } } } } void GetShortestPaths(int s,int* dist,vector<int>* paths){//paths是二維鏈表 dijkstra(s); for(int i=0;i<n;i++){ dist[i]=d[i]; paths[i].clear(); int t=i; paths[i].push_back(t); while(t!=s){ paths[i].push_back(edges[p[t]].from); t=edges[p[t]].from; } reverse(paths[i].begin(),paths[i].end()); } } }; Dijkstra solver; int d1[maxn],d2[maxn]; vector<int>paths1[maxn],paths2[maxn]; int main() { // std::ios::sync_with_stdio(false); // std::cin.tie(0); // std::cout.tie(0); int kase=0,N,S,E,M,K,X,Y,Z; while(scanf("%d%d%d%d", &N, &S, &E, &M) == 4) { solver.init(N); S--;E--; for(int i=0;i<M;i++){ scanf("%d%d%d", &X, &Y, &Z); X--; Y--; solver.AddEdge(X,Y,Z); solver.AddEdge(Y,X,Z); } solver.GetShortestPaths(S,d1,paths1); solver.GetShortestPaths(E,d2,paths2); int ans=d1[E]; vector<int>path=paths1[E]; int midpoint=-1; scanf("%d", &K); for(int i=0;i<K;i++){ scanf("%d%d%d", &X, &Y, &Z); X--; Y--; for(int j=0;j<2;j++){ if(d1[X]+d2[Y]+Z<ans){ ans=d1[X]+d2[Y]+Z; path=paths1[X]; for(int p=paths2[Y].size()-1;p>=0;p--) path.push_back(paths2[Y][p]); midpoint=X; } swap(X,Y); } } if(kase != 0) printf("\n"); kase++; for(int i = 0; i < path.size()-1; i++) printf("%d ", path[i]+1); printf("%d\n", E+1); if(midpoint == -1) printf("Ticket Not Used\n"); else printf("%d\n", midpoint+1); printf("%d\n", ans); } return 0; }
訓練指南 UVA - 11374(最短路Dijkstra + 記錄路徑 + 模板)