您的位置:首页 > 大数据 > 人工智能

文章标题 UVA 11374 : Airport Express(最短路--dijkstra)

2017-03-11 15:13 405 查看

Airport Express

题意:有两种机票,一种经济机票,另一种商务几票,商务机票比较快,但比较贵。现在要从s地点到达e地点,然后期间最多只能用一张商务几票,第一行将路线的每个站输出来,第二行如果有使用商务机票,将机票的起始地点输出来,没有使用就输出Ticket Not Used,第三行输出最短的时间

分析:这是一道以dijkstra为基础的题目,首先可以求出只有经济机票时起始点s到达其他顶点的最短距离dis1,同时保存父节点par1,同样求出终点e到达其他地点的最短距离dis2和par2,然后枚举每一条商务机票u,v,val,(u–>v||v–>u花费val的时间)判断dis1[u]+val+did2[v]<当前的最短时间,如果小于,说明乘坐这条路线用的时间是最短的,然后保存此时的u,v,最后通过par1和par2找出路线经过的站点。

代码:

#include<iostream>
#include<string>
#include<cstdio>
#include<cstring>
#include<vector>
#include<math.h>
#include<map>
#include<queue>
#include<algorithm>
using namespace std;
const int inf = 0x3f3f3f3f;
const int maxn = 505;
int n,s,e;
int m,k;

struct node{
int v;
int cost;
node (int v_=0,int cost_=0){
v=v_;
cost=cost_;
}
bool operator <(const node &t)const {
return cost>t.cost;
}
};
struct Edge{
int v,cost;
Edge (int v_=0,int cost_=0){
v=v_;
cost=cost_;
}
};

vector<Edge>E[maxn];//用来存储图的
int vis[maxn];
int par1[maxn];
int par2[maxn];
int dis1[maxn];
int dis2[maxn];
int path[maxn];
int ans;

void dijkstra(int n,int start,int dis[],int par[]){
memset (vis,0,sizeof (vis));
for (int i=0;i<=n;i++)dis[i]=1000000000;
priority_queue<node>q;
while (!q.empty())q.pop();
dis[start]=0;
q.push(node(start,0));
node tmp;
while (!q.empty()){
tmp=q.top();q.pop();
int u=tmp.v;
if (vis[u])continue;//如果这个点的最短距离已经找到,就直接跳过
vis[u]=1;
for (int i=0;i<E[u].size();i++){//枚举邻接点
int v=E[u][i].v;
int cost=E[tmp.v][i].cost;
if (!vis[v]&&dis[u]+cost<dis[v]){//如果还有更短的就松弛
dis[v]=dis[u]+cost;
par[v]=u;
q.push(node(v,dis[v]));
}
}
}
}

int main ()
{
int cnt=0;
while (scanf ("%d%d%d",&n,&s,&e)!=EOF){
if (cnt++)printf ("\n");
scanf ("%d",&m);
for (int i=0;i<=n;i++)E[i].clear();
int u,v1,cost;
for (int i=0;i<m;i++){
scanf ("%d%d%d",&u,&v1,&cost);
E[u].push_back(Edge(v1,cost));
E[v1].push_back(Edge(u,cost));
}
dijkstra(n,s,dis1,par1);//第一次求最短路
dijkstra(n,e,dis2,par2);//第二次
scanf ("%d",&k);
int ans=dis1[e];//初始的最短距离
vector<int>v;
v.clear();
int tmp=s;
int ticket=-1;
int ticket_v;
for (int i=0;i<k;i++){//枚举
scanf ("%d%d%d",&u,&v1,&cost);
for (int j=0;j<2;j++){
if (dis1[u]+cost+dis2[v1]<ans){//找到更短的
ans=dis1[u]+cost+dis2[v1];
ticket=u;//保存u和v
ticket_v=v1;
}
swap(u,v1);//交换一下,有两种可能
}
}
if (ticket==-1){//不用商务机票的情况
tmp=s;
while (1){  //直接求路线
v.push_back(tmp);
if (tmp==e)break;
tmp=par2[tmp];
}
printf ("%d",v[0]);
for (int i=1;i<v.size();i++){
printf (" %d",v[i]);
}
printf ("\n");
printf ("Ticket Not Used\n");
printf ("%d\n",ans);
}
else {//用了商务机票的情况
tmp=ticket;
while (1){//先求s-->u(即ticket)
v.push_back(tmp);
if (tmp==s)break;
tmp=par1[tmp];
}
reverse(v.begin(),v.end());//需要反转一下
tmp=ticket_v;
while (1){//求v-->e的路线
v.push_back(tmp);
if (tmp==e)break;
tmp=par2[tmp];
}
printf ("%d",v[0]);//输出答案
for (int i=1;i<v.size();i++){
printf (" %d",v[i]);
}
printf ("\n%d\n",ticket);
printf ("%d\n",ans);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  uva dijkstra