在W市中,旅游大巴是市民从市内去景区A的首选交通工具。旅游大巴分为普通线和快速线两种,线路、速度和价钱都不同。你有一张快速线车票,可以坐一站快速线,而其他时候只能乘坐普通线。假设换乘时间忽略不计,你的任务是找一条去景点A最快的线路。
输入包含多组数据。每组数据第一行为3个整数N,S和E(2≤N≤500,1≤S,E≤100),即旅游大巴中的停靠站总数,起点和终点(即景点A所在站)编号。下一行包含一个整数M(1≤M≤1000),即普通线的路段条数。以下M行每行3个整数X,Y,Z(1≤X,Y≤N,1≤Z≤100),表示可以乘坐普通线在站点X和站点Y之间往返,其中单程需要Z分钟。下一行为快速线的路段条数K(1≤K≤1000),以下K行是这些路段的描述,格式同普通线。所有路段都是双向的,但有可能必须使用快速车票才能到达景点A。保证最优解唯一。
对于每组数据,输出3行。第一行按访问顺序给出经过的各个站点(包括起点和终点),第二行是换乘快速线的车站编号(如果没有快速线车票,输出Ticket Not Used),第三行是总时间。
注意:输出时,每两组数据之间要加一个空行。并且不会过滤行末空格
输入样例:
4 1 4 4 1 2 2 1 3 3 2 4 4 3 4 5 1 2 4 3
输出样例:
1 2 4 2 5
#include<bits/stdc++.h>
using namespace std;
#define int long long
int head[10005*2];
int dist[10005*2];
int vis[10005*2],dis[10005*2];
int n,m,l,s,t,ans;
int p[1000];
int wa[1000];
struct node{
int to,w,next;
}f[10005];
int cnt;
struct da{
int x,y;
};
void add(int a,int b,int c){
f[cnt].to=b;
f[cnt].w=c;
f[cnt].next=head[a];
head[a]=cnt++;
}
struct cmp{
bool operator()(da a,da b){
return a.y>b.y;
}
};
void bfs(int x){
priority_queue<da,vector<da>,cmp>q;
memset(dist,0x3f,sizeof(dist));
memset(vis,0,sizeof(vis));
memset(p,-1,sizeof(p));
dist[x]=0;
q.push({x,dist[x]});
while(!q.empty()){
da z=q.top();
q.pop();
if(vis[z.x])continue;
vis[z.x]=0;
for(int i=head[z.x];i!=-1;i=f[i].next){
int g=f[i].to;
if(dist[g]>dist[z.x]+f[i].w){
dist[g]=dist[z.x]+f[i].w;
q.push({g,dist[g]});
p[g]=z.x;
}
}
}
}
signed main(){
int naa=0;
//判段换行
while(cin>>n>>s>>t){
cnt=0;
if(naa){
cout<<endl;
}
memset(head,-1,sizeof(head));
memset(p,-1,sizeof(p));
memset(dis,0x3f,sizeof(dis));
cin>>m;
while(m--){
int a,b,c;
cin>>a>>b>>c;
add(a,b,c);
add(b,a,c);
}
bfs(s);
for(int i=1;i<=n;i++){
dis[i]=dist[i];
wa[i]=p[i];
}
bfs(t);
//qx等于终点,qx=-1可以排除第三给样例点的打印路径问题
int qx=t,qy=-1;
int k;
cin>>k;
ans=dist[s];
while(k--){
int a,b,c;
cin>>a>>b>>c;
if(dis[a]==0x3f3f3f3f3f3f3f3f||dist[b]==0x3f3f3f3f3f3f3f3f){
continue;
}
if(dist[b]+dis[a]+c<ans){
ans=dist[b]+dis[a]+c;
qx=a;
qy=b;
}
}
vector<int>aps;
int z=qx;
while(z!=-1){
aps.push_back(z);
z=wa[z];
}
reverse(aps.begin(),aps.end());
z=qy;
while(z!=-1){
aps.push_back(z);
z=p[z];
}
// 打印路径
for(int i=0;i<aps.size();i++){
if(i!=0)cout<<" ";
cout<<aps[i];
}
cout<<endl;
if(qx==t&&qy==-1){
cout<<"Ticket Not Used"<<endl;
cout<<ans<<endl;
}else{
cout<<qx<<endl;
cout<<ans<<endl;
}
naa++;
}
return 0;
}