题意:
题目弄不过来就直接上题意了(反正题目那么长也不会有人看。。)。
无向图,给你n个地点,和一个人的起点和终点,有m条经济舱的线,k条商务舱的线,每条路线都是a b v 表示ab之间要花费v时间,这个人只能坐一次商务舱,,问怎么走使时间最短。输出用时最短最短的路线,如果不需要坐商务舱,那么输出Ticket Not Used 不然要输出商务舱在哪里上了车,最后输出最短的时间,同时答案和答案之间要有空行。
做法:
dijkstra啦...其实很简单,但就是容易敲错才敲了好久,希望之后毛病少出吧。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
typedef long long ll;
const int maxn=1000;
const int inf=0x3f3f3f3f;
int n,m,head[maxn],now,st,en,pre1[maxn],pre2[maxn];
int dist1[maxn],distn[maxn],vis[maxn];
struct node{
int to,next,w;
}e[5000];
struct Node{
int dis,id;
Node(int dis,int id):dis(dis),id(id){}
bool operator < (const Node &a)const{
return dis>a.dis;
}
};
void add(int u,int v,ll w){
e[now].to=v; e[now].w=w;
e[now].next=head[u],head[u]=now++;
}
void dij(int st,int dis[],int pre[]){
memset(vis,0,sizeof(vis));
dis[st]=0;
priority_queue<Node> q;
q.push(Node(0,st));
vis[st]=1;
while(!q.empty()){
int u=q.top().id; q.pop();
vis[u]=1;
for(int i=head[u];~i;i=e[i].next){
int v=e[i].to;
if(vis[v]) continue;
if(dis[v]-e[i].w>dis[u]){
dis[v]=dis[u]+e[i].w;
q.push(Node(dis[v],v));
pre[v]=u;
}
}
}
}
void cou(int now){
if(pre1[now]!=-1)
cou(pre1[now]);
if(now!=en)
printf("%d ",now);
else printf("%d\n",now);
}
int main(){
int x,y,z,k,cas=0,xx,yy,ww;
while(~scanf("%d%d%d",&n,&st,&en)){
if(cas) printf("\n");
else cas++;
now=0;
for(int i=1;i<=n;i++){
dist1[i]=distn[i]=inf;
head[i]=pre1[i]=pre2[i]=-1;
}
scanf("%d",&m);
for(int i=1;i<=m;i++){
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);
add(y,x,z);
}
dij(st,dist1,pre1);
dij(en,distn,pre2);
scanf("%d",&k);
int ans=dist1[en],s=-1,t=-1;
for(int i=0;i<k;i++){
scanf("%d%d%d",&xx,&yy,&ww);
int cur=dist1[xx]+distn[yy]+ww;
if(cur<ans){
ans=cur;
s=xx,t=yy;
}
cur=dist1[yy]+distn[xx]+ww;
if(cur<ans){
ans=cur;
s=yy,t=xx;
}
}
if(s>0){
cou(s);
int now=t;
while(now!=en){
printf("%d ",now);
now=pre2[now];
}
printf("%d\n",en);
}
else {
cou(en);
}
if(s>0) printf("%d\n",s);
else printf("Ticket Not Used\n");
printf("%d\n",ans);
}
return 0;
}