UVA 11374 Airport Express(优先队列优化dijstra + 枚举)

UVA Airport Express

题意:在Iokh市机场快线分为经济线和商业线。线路和速度价格都不同。你只有一张商业线车票,即最多只能坐一站商业线,其他时候只能坐经济线。找出一条去机场最快的线路。

思路:因为商业线只能坐一站,假如乘坐一条商业线(a,b),那么起点到a,b到终点都必须是最短路。所以先预处理起点和终点到其他所有点的最短路,分别记为f()和g(),两次dijstra即可。那么我们只需枚举每条商业线求出所有的f(a)+T(a,b)+g(b)然后求最小即可。

1w是TLE,改成了优先队列优化的dijstra,白书上的模板。

2w是RE,题目中说边数最多1000条,开到1010仍然re,果断开到10010。

#include <stdio.h>
#include <algorithm>
#include <set>
#include <map>
#include <vector>
#include <math.h>
#include <string.h>
#include <queue>
#define LL long long
#define _LL __int64

using namespace std;
const int INF = 0x3f3f3f3f;
const int maxn = 510;
const int maxm = 10100;

struct node
{
	int u,v,w,next;
}edge[maxm];

int cnt,head[maxm];
int n,m,k;
int s,t;
int dis_s[maxm],dis_t[maxm];
int pre_s[maxm],pre_t[maxm];
int ans;
int path[maxm];

void init()
{
	cnt = 0;
	memset(head,-1,sizeof(head));

}

void add(int u, int v, int w)
{
	edge[cnt] = ((struct node){u,v,w,head[u]});
	head[u] = cnt++;
}

void dijstra(int u)
{
	int dis[maxn],pre[maxn];
	priority_queue <pair<int,int>,vector<pair<int,int> >, greater<pair<int,int> > > que;
	bool vis[maxn];

	memset(vis,false,sizeof(vis));
	for(int i = 1; i <= n; i++)
	{
		dis[i] = (i == u ? 0 : INF);
	}

	que.push(make_pair(dis[u],u));
	pre[u] = -1;

	while(!que.empty())
	{
		pair<int,int> p = que.top();
		que.pop();
		int v = p.second;
		if(vis[v]) continue;
		vis[v] = true;

		for(int i = head[v]; i != -1; i = edge[i].next)
		{
			if( dis[edge[i].v] > dis[v] + edge[i].w)
			{
				dis[edge[i].v] = dis[v] + edge[i].w;
				pre[edge[i].v] = v;
				que.push(make_pair(dis[edge[i].v],edge[i].v));
			}
		}
	}

	if(u == s)
	{
		memcpy(dis_s,dis,sizeof(dis));
		memcpy(pre_s,pre,sizeof(pre));
	}
	if(u == t)
	{
		memcpy(dis_t,dis,sizeof(dis));
		memcpy(pre_t,pre,sizeof(pre));
	}
}

void solve()
{
	int mid_u,mid_v,u,v,w;
	int flag = 0;
	int cnt,tmp;
	scanf("%d",&k);
	for(int i = 0; i < k; i++)
	{
		scanf("%d %d %d",&u,&v,&w);

		if(dis_s[u] + dis_t[v] + w < ans)
		{
			ans = dis_s[u] + dis_t[v] + w;
			mid_u = u;
			mid_v = v;
			flag = 1;
		}
		if(dis_s[v] + dis_t[u] + w < ans)
		{
			ans = dis_s[v] + dis_t[u] + w;
			mid_u = v;
			mid_v = u;
			flag = 1;
		}
	}

	if(flag == 0)
	{
		cnt = 0;
		tmp = t;
		path[cnt++] = tmp;
		while( pre_s[tmp] != -1)
		{
			path[cnt++] = pre_s[tmp];
			tmp = pre_s[tmp];
		}
		for(int i = cnt-1; i > 0; i--)
			printf("%d ",path[i]);
		printf("%d\n",path[0]);

		printf("Ticket Not Used\n");
	}
	else
	{
		cnt = 0;
		tmp = mid_u;
		path[cnt++] = tmp;
		while(pre_s[tmp] != -1)
		{
			path[cnt++] = pre_s[tmp];
			tmp = pre_s[tmp];
		}
		for(int i = cnt-1; i >= 0; i--)
			printf("%d ",path[i]);

		cnt = 0;
		tmp = mid_v;
		path[cnt++] = tmp;
		while(pre_t[tmp] != -1)
		{
			path[cnt++] = pre_t[tmp];
			tmp = pre_t[tmp];
		}
		for(int i = 0; i < cnt-1; i++)
			printf("%d ",path[i]);
		printf("%d\n",path[cnt-1]);

		printf("%d\n",mid_u);
	}
	printf("%d\n",ans);
}

int main()
{
	int item = 0;
	while(~scanf("%d %d %d",&n,&s,&t))
	{
		if(item)
			printf("\n");
		init();
		int u,v,w;
		scanf("%d",&m);
		for(int i = 0; i < m; i++)
		{
			scanf("%d %d %d",&u,&v,&w);
			add(u,v,w);
			add(v,u,w);
		}

		dijstra(s);	//预处理
		dijstra(t);

		ans = dis_s[t];

		solve();
		item++;
	}
	return 0;
}
时间: 2024-10-06 14:59:01

UVA 11374 Airport Express(优先队列优化dijstra + 枚举)的相关文章

UVA 11374 - Airport Express(dijstra)

UVA 11374 - Airport Express 题目链接 题意:给定一些经济线,和一些商务线,商务线最多坐一次,每个线有一个时间,问最短时间 思路:从起点,终点各做一次dijstra,然后枚举商务线,就可以算出总时间,最后求出总时间最少 代码: #include <cstdio> #include <cstring> #include <vector> #include <queue> using namespace std; #define INF

UVA - 11374 Airport Express (Dijkstra模板+枚举)

Description Problem D: Airport Express In a small city called Iokh, a train service, Airport-Express, takes residents to the airport more quickly than other transports. There are two types of trains in Airport-Express, the Economy-Xpress and the Comm

UVA 11374 Airport Express 机场快线 Dijistra+路径

题目链接:UVA 11374 Airport Express Airport Express Time Limit: 1000MS   Memory Limit: Unknown   64bit IO Format: %lld & %llu [Submit]   [Go Back]   [Status] Description Problem D: Airport Express In a small city called Iokh, a train service, Airport-Expr

uva 11374 Airport Express(最短路)

uva 11374 Airport Express In a small city called Iokh, a train service, Airport-Express, takes residents to the airport more quickly than other transports. There are two types of trains in Airport-Express, the Economy-Xpress and the Commercial-Xpress

uva 10537 Toll! Revisited(优先队列优化dijstra及变形)

Toll! Revisited 大致题意:有两种节点,一种是大写字母,一种是小写字母.首先输入m条边,当经过小写字母时需要付一单位的过路费,当经过大写字母时,要付当前财务的1/20做过路费.问在起点最少需要带多少物品使到达终点时还有k个物品.当有多条符合条件的路径时输出字典序最小的一个. 思路:已知终点的权值,那么可以从终点向前推.求终点到起点的最短路径,然后按字典序打印路径. 比较难处理的是:向前推时前驱节点的权值计算.列个方程算算就可以了,主要时不能整除的情况. 计算前驱结点dis值的时候,

uva 11374 Airport Express(spfa 邻接表+队列)

Problem D: Airport Express In a small city called Iokh, a train service, Airport-Express, takes residents to the airport more quickly than other transports. There are two types of trains in Airport-Express, the Economy-Xpress and theCommercial-Xpress

UVA 11374 Airport Express (最短路dijkstra+枚举+边的输出)

题意:给你一个数n,s,e,n为有多少个车站,s,e是起点和终点,接下来有m条经济路线,再接下来有k条商业线,你最多只能座一条商业线,现在要你求出从s到e的最短路,并输出它所经过的节点还有座商业线的车站. 思路:实际上这道题就是考你对dijkstra的理解了,其中d数组的含意是起点到第i个点的最短距离,那么每次寻找商业路线的时候,是不是可以比较d[e]跟从起点到点u的最小值+从终点到v的最小值+w[u][v].最后我们可以根据递归输出路径了. AC代码: #include<cstdio> #i

uva 11374 Airport Express (Dijkstra)

 题意:在Iokh市中,机场快线是市民从市内去机场的首选交通工具.机场快线分为经济线和商业线两种,线路,速度和价钱都不同.你有一张商业线车票,可以做一站商业线,而其他时候只能乘坐经济线.假设换乘时间忽略不计,你的任务是找一条去机场最快的路线.. 分析:枚举商业线T(a,b),则总时间为f(a)+T(a,b)+g(b);f和g用两次dijkstra来计算,以S为起点的dijkstra和以E为起点的dijkstra: 注意:有可能只做慢车到达不了终点,这时必须做某站快车,如果按照坐慢车一定能到达

UVA - 11374 Airport Express(dijkstra)

题目大意:机场快线分为经济线和商业线两种,线路,速度和价钱都不同.你有一张商业线车票,可以坐一站商业线,而其他时候只能坐经济线 现在给你起点和终点,要求你找出一条最快的线路 解题思路:不得不说,这题还是有点恶心的 要进行两次的dijkstra,一次以起点为源点,得到的数组d1表示结点和起点最近距离 另一次以终点为源点,得到数组d2,表示结点和终点最近的距离 现在M张商业票,给出的地点为x,y,z 那么有两种选择方式,一种是从起点走到x,然后使用商业票,然后再从y走到终点,那么距离就为 d1[x]