题目链接
题意:在Iokh市中,机场快线是市民从市内去机场的首选交通工具。机场快线分为经济线和商业线两种,线路,速度和价钱都不同。你有一张商业线车票,可以做一站商业线,而其他时候只能乘坐经济线。假设换乘时间忽略不计,你的任务是找一条去机场最快的路线。。
solution:dijkstra/spfa预处理出每个点到起点和终点的距离,再枚举商业线,复杂度O(mlogn+k)
#include <queue>
#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define Inf 0x3f3f3f3f
const int N = 505;int n, ans, S, E;
int d1[N], d2[N], p1[N], p2[N];
struct Edge{int u, v, w;Edge(int u, int v, int w):u(u),v(v),w(w){}
};
struct HeapNode{int dist, u;bool operator<(const HeapNode& rhs) const{return dist>rhs.dist;}
};
struct Dijkstra{int n;int d[N], p[N];bool vis[N];vector<Edge>edges;vector<int>G[N]; void init(int n){this->n=n;for ( int i=1; i<=n; i++ ) G[i].clear();edges.clear();}void addeage(int u, int v, int w){edges.push_back((Edge){u,v,w});int m=edges.size();G[u].push_back(m-1);}void dijkstra(int s){for ( int i=1; i<=n; i++ ) d[i]=Inf, p[i]=0;memset(vis,0,sizeof(vis));priority_queue<HeapNode> Q;Q.push((HeapNode){
0,s});d[s]=0;while( !Q.empty() ){HeapNode x=Q.top(); Q.pop();int u=x.u;if( vis[u] ) continue;vis[u]=1;for ( int i=0; i<G[u].size(); i++ ){Edge& e=edges[G[u][i]];if( d[e.v] > d[u]+e.w ){d[e.v]=d[u]+e.w;p[e.v]=e.u;Q.push((HeapNode){d[e.v],e.v});}}}}};struct SPFA{int n;vector<Edge> edges;vector<int> G[N];int d[N], p[N];bool inq[N];void init(int n){this->n=n;for ( int i=1; i<=n; i++ ) G[i].clear();edges.clear();}void addeage(int u, int v, int w){edges.push_back((Edge){u,v,w});int m=edges.size();G[u].push_back(m-1);}void spfa(int s){for ( int i=1; i<=n; i++ ) d[i]=Inf, inq[i]=false, p[i]=0;queue<int> Q;Q.push(s);d[s]=0;inq[s]=true;while( !Q.empty() ){int u=Q.front(); Q.pop();inq[u]=false;for ( int i=0; i<G[u].size(); i++ ){Edge& e=edges[G[u][i]];if( d[e.v]>d[u]+e.w ){d[e.v]=d[u]+e.w;p[e.v]=u;if( !inq[e.v] ){inq[e.v]=true;Q.push(e.v); } }}}}
};
SPFA solve;inline int read(){int x=0, f=1; char ch=getchar();while( !isdigit(ch) ) { if(ch=='-') f=-1; ch=getchar(); }while( isdigit(ch) ) { x=x*10+ch-'0'; ch=getchar(); }return x*f;
} void ptX(int u){if( u==S ){printf("%d", u );return ;}ptX(p1[u]);printf(" %d", u);
}
void ptY(int u){printf(" %d", u );if( u==E ) return ;ptY(p2[u]);
}
int main(){int k=0;while( scanf("%d%d%d", &n, &S, &E)==3 ){if( k++ ) printf("\n");solve.init(n);int m;
scanf("%d", &m);for ( int i=1; i<=m; i++ ){int x, y, z;scanf("%d%d%d", &x, &y, &z );solve.addeage(x,y,z), solve.addeage(y,x,z);}solve.spfa(S);for ( int i=1; i<=n; i++ ) d1[i]=solve.d[i], p1[i]=solve.p[i];solve.spfa(E);for ( int i=1; i<=n; i++ ) d2[i]=solve.d[i], p2[i]=solve.p[i];scanf("%d", &m);int X=0, Y=0; ans=d1[E];for ( int i=1; i<=m; i++ ){int x, y, z;scanf("%d%d%d", &x, &y, &z );if( d1[x]+d2[y]+z < ans ){ans=d1[x]+d2[y]+z;X=x, Y=y;}if( d1[y]+d2[x]+z < ans ){ans=d1[y]+d2[x]+z;X=y, Y=x;} }if( X!=Y ) {ptX(X), ptY(Y); printf("\n");printf("%d\n", X);printf("%d\n", ans);}else{ptX(E);printf("\n");printf("Ticket Not Used\n");printf("%d\n", ans);}}
}