week7 作业B TT的旅行日记

TT 的旅行日记

众所周知,TT 有一只魔法猫。
今天他在 B 站上开启了一次旅行直播,记录他与魔法猫在喵星旅游时的奇遇。 TT 从家里出发,准备乘坐猫猫快线前往喵星机场。猫猫快线分为经济线和商业线两种,它们的速度与价钱都不同。当然啦,商业线要比经济线贵,TT 平常只能坐经济线,但是今天 TT 的魔法猫变出了一张商业线车票,可以坐一站商业线。假设 TT 换乘的时间忽略不计,请你帮 TT 找到一条去喵星机场最快的线路,不然就要误机了!

Input

输入包含多组数据。每组数据第一行为 3 个整数 N, S 和 E (2 ≤ N ≤ 500, 1 ≤ S, E ≤ 100),即猫猫快线中的车站总数,起点和终点(即喵星机场所在站)编号。
下一行包含一个整数 M (1 ≤ M ≤ 1000),即经济线的路段条数。
接下来有 M 行,每行 3 个整数 X, Y, Z (1 ≤ X, Y ≤ N, 1 ≤ Z ≤ 100),表示 TT 可以乘坐经济线在车站 X 和车站 Y 之间往返,其中单程需要 Z 分钟
下一行为商业线的路段条数 K (1 ≤ K ≤ 1000)。
接下来 K 行是商业线路段的描述,格式同经济线。
所有路段都是双向的,但有可能必须使用商业车票才能到达机场。保证最优解唯一。

Output

   对于每组数据,输出3行。第一行按访问顺序给出 TT 经过的各个车站(包括起点和终点),第二行是 TT 换乘商业线的车站编号(如果没有使用商业线车票,输出"Ticket Not Used",不含引号),第三行是 TT 前往喵星机场花费的总时间。
**本题不忽略多余的空格和制表符,且每一组答案间要输出一个换行**

Smple Input

4 1 4
4
1 2 2
1 3 3
2 4 4
3 4 5
1
2 4 3

Sample Output

1 2 4
2
5

我的思路:
这道题的题意是,要从一个车站X到另一个车站Y,过程中要走经济线(或者经济线+一条商业线),找到最短的路径。这里的想法可以是利用求最短路的算法,外加一个记录前驱节点的数组pre,来记录路径。对于商业线的选择上,可以对于每条商业线a->b,找到起点和终点分别到a和b的距离,取拼接最小值+商业线a->b的权重w,即为经过当前商业线的最短路径。利用这样的思想,在实际操作中,只要进行两边求最短路的操作(从起点开始/从终点开始),记录两个距离数组,然后对于每条商业线遍历计算距离,最后再和不走商业线做一个对比就可以了。

我的总结:
最短路算法包括Dijkstra、Bellman_ford,SPFA,都应该灵活运用,并且不要搞混。

我的代码:

#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;

const long long inf = 5*1e8; 

struct Edg
{
	long long to,next,w;
		
}edg[20001];
bool fl=false;
long long dis[10001][2],pre[10001][2],inq[10001][2],n,nn,sta,s,e,m,x0,y0,w0,head[1001],ind,kn,min_dis,ans1,ans2;
priority_queue<pair<int,int> > que;
void add(long long x,long long y,long long wei)
{
	edg[ind].to=y;
	edg[ind].next=head[x];
	edg[ind].w=wei;
	head[x]=ind;
	ind++;
}

void print0(long long xx)
{
	if(xx==s) {
	printf("%d",s);
	return;}
	print0(pre[xx][0] );
	printf(" %d",xx);
}
void print1(long long xx)
{
	while(xx!=e)
	{
	printf("%d ",xx);
	xx=pre[xx][1];
	}
	printf("%d\n",xx);
}

void init()
{
	for(long long i=1;i<n+1;i++)
	{
		dis[i][0]=inf;
		dis[i][1]=inf;
		pre[i][0]=0;
		pre[i][1]=0;
		inq[i][0]=0;
		inq[i][1]=0;
		head[i]=0;
	}
 } 

void Bell(long long jug)
{
	if(jug==s) kn=0,sta=s;
	else kn=1,sta=e;
	dis[sta][kn]=0;
	que.push(make_pair(0,sta));
	while(!que.empty())
	{
		long long o=que.top().second;
		que.pop();
		if(inq[o][kn]) continue;
		inq[o][kn]=1;
		for(long long i=head[o];i;i=edg[i].next)
		{
			if(dis[edg[i].to][kn]>dis[o][kn]+edg[i].w){
				dis[edg[i].to][kn]=dis[o][kn]+edg[i].w;
				pre[edg[i].to][kn]=o;
				que.push(make_pair(-dis[edg[i].to][kn],edg[i].to));
			}
		}
	}
}

int main()
{
	while(scanf("%d%d%d%d",&n,&s,&e,&m)!=EOF)
	{
	ind=1;
	init();
	for(long long i=0;i<m;i++)
	{
		scanf("%d%d%d",&x0,&y0,&w0);
		add(x0,y0,w0);
		add(y0,x0,w0);
	}
	Bell(s);
	Bell(e);
	scanf("%d",&nn);
	min_dis=inf;
	ans1=ans2=0;
	for(long long i=0;i<nn;i++)
	{
		scanf("%d%d%d",&x0,&y0,&w0);
		if(min(dis[x0][0]+dis[y0][1]+w0,dis[y0][0]+dis[x0][1]+w0) < min_dis) 
		{
		min_dis=min(dis[x0][0]+dis[y0][1]+w0,dis[y0][0]+dis[x0][1]+w0);
		if(dis[x0][0]+dis[y0][1]+w0 < dis[y0][0]+dis[x0][1]+w0) ans1=x0,ans2=y0;
		else ans1=y0,ans2=x0;}
	}
	if(min_dis > dis[e][0]) min_dis=dis[e][0],ans1=0;
	if(fl) printf("\n");
	else fl=true;
	if(ans1)
	{//printf("**1**");
		print0(ans1);
		printf(" ");
		print1(ans2);
		printf("%d\n%d\n",ans1,min_dis);
	}
	else
	{//printf("**2**");
		print0(e);
		printf("\nTicket Not Used\n%d\n",min_dis);
	}
	}
	return 0;
} 
发布了26 篇原创文章 · 获赞 0 · 访问量 434

猜你喜欢

转载自blog.csdn.net/qq_43738677/article/details/105305652
今日推荐