Week7 assignment-B-TT's travel diary

topic

As we all know, TT has a magic cat.
Today, he started a live travel live broadcast on station B, recording his adventures with the magic cat while traveling on the cat. TT departs from home and prepares to take the Mao Mao Express to the Meow Star Airport. The Maomao Express Line is divided into two types: economic line and commercial line, and their speed and price are different. Of course, the commercial line is more expensive than the economic line. TT usually can only take the economic line, but today the magic cat of TT has turned into a commercial line ticket, which can take one stop on the commercial line. Assuming that the TT transfer time is negligible, please help TT find the fastest route to Meow Star Airport, otherwise you will miss the flight! Input input contains multiple sets of data. The first line of each group of data is 3 integers N, S and E (2 ≤ N ≤ 500, 1 ≤ S, E ≤ 100), that is, the total number of stations in the Maomao Express Line, the starting point and the ending point (that is, the station where the Meow Star Airport is located )Numbering.
The next line contains an integer M (1 ≤ M ≤ 1000), which is the number of road sections of the economic line.
Next, there are M rows, each with 3 integers X, Y, Z (1 ≤ X, Y ≤ N, 1 ≤ Z ≤ 100), indicating that TT can take the economy line to and from station X and station Y, of which one way It takes Z minutes.
The next line is the number of road sections K (1 ≤ K ≤ 1000) of the commercial line.
The next K line is the description of the commercial line section, the format is the same as the economic line.
All sections are two-way, but it may be necessary to use a commercial ticket to reach the airport. Ensure that the optimal solution is unique. Output For each group of data, output 3 lines. The first line lists the stations (including the start and end points) passed by TT in the order of access, and the second line is the station number of the TT transfer commercial line (if no commercial line ticket is used, output "Ticket Not Used" without the quotation marks ), the third line is the total time spent by TT to Meow Star Airport.
This question does not ignore extra spaces and tabs, and a newline should be output between each set of answers

Input sample

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

Ideas

Insert picture description here
Insert picture description here

solution

1. Do Dijkstra again from place A, record the shortest path and precursor node from each station to place A without taking the commercial line, do the same operation from place B, and then enumerate each Commercial station (u,v,w), get min{dis1[u]+dis2[v]+w, dis1[v]+dis2[u]+w, dis1[e]}. When outputting the stations passing from the starting point to the ending point, it is necessary to traverse the array of the predecessor nodes and use a new array to store the elements obtained by the traversal. Pay attention to the order of the output.
2. Because priority_queue<pair<int,int>> is the largest heap, if you want to make it into the smallest heap, you can use q.push(make_pair(-dis[y],y));
3. pair<int,int >By default, sort by first.

error

1. Pay attention to judging the size of the edge pool. Although the input is n edges, considering that two edges need to be added to the edge pool for each edge, it is necessary to open the edge pool to double the number of edges.
2. Note that v1 and v2 may be s or e, so pre[v1/v2]==s cannot be used directly, e is used as the end condition of while, consider that the predecessor nodes of v1 and v2 can be assigned to -1, and then use pre[v1/v2]= = -1 as the termination condition of while
3. Note that this question strictly controls the output format. It is necessary to output a newline between each set of data, and no newline character is output at the end of all data.
4. To use ios::sync_with_stdio(false); turn off synchronization, otherwise it will be TE.

Code

#include<iostream>
#include<bits/stdc++.h>
using namespace std;
const int maxm=2010;//注意虽然题目给出输入1000条无向边,但因为要往边池中加入两个方向的边,所以应该将边池开为两倍大小 
const int maxn=501;
const int inf=5*1e8;
struct Edge
{
    
    
	int to,next,w;
}e[maxm];
int head[maxn],tot,n,m,dis1[maxn],dis2[maxn],pre1[maxn],pre2[maxn];
bool vis[maxn]; 
void add(int x,int y,int w)
{
    
    
	e[++tot].to=y;
	e[tot].next=head[x];
	e[tot].w=w;
	head[x]=tot;
}
priority_queue<pair<int,int> > q;

void dijkstra(int s,int *dis,int *pre)
{
    
    
	while(q.size())
		q.pop();
	memset(vis,0,sizeof(vis));
	for(int i=1;i<=n;i++)
		dis[i]=inf;
	pre[s]=-1;
	dis[s]=0;
	q.push(make_pair(0,s));
	while(q.size())
	{
    
    
		int x=q.top().second;
		q.pop();
		if(vis[x]) continue;
		vis[x]=1;
		for(int i=head[x];i;i=e[i].next)
		{
    
    
			int y=e[i].to,w=e[i].w;
			if(dis[y]>dis[x]+w)
			{
    
    
				pre[y]=x;
				dis[y]=dis[x]+w;
				q.push(make_pair(-dis[y],y));
			}
		}
	}
}
int main()
{
    
    
	int s,e,k,first=0;
	ios::sync_with_stdio(false);
	while((scanf("%d%d%d",&n,&s,&e))!=EOF)
	{
    
    
		if(first) 		
			printf("\n");//不要忘记每组数据之间还要输出一个空行。 
		first=1;
		scanf("%d",&m);
		tot=1;
		memset(head,0,sizeof(head));
		for(int i=0;i<m;i++)
		{
    
    
			int x,y,z;
			scanf("%d%d%d",&x,&y,&z);
			add(x,y,z);
			add(y,x,z);
		}
		dijkstra(s,dis1,pre1);
		dijkstra(e,dis2,pre2);
		int len=dis1[e];
		int v1,v2,flag=0;
		scanf("%d",&k);
		for(int i=0;i<k;i++)
		{
    
    
			int x,y,z;
			scanf("%d%d%d",&x,&y,&z);
			int len1=dis1[x]+z+dis2[y];
			if(len1<len)
			{
    
    
				len=len1;
				flag=1;
				v1=x;
				v2=y;
			}
			len1=dis1[y]+z+dis2[x];
			if(len1<len)
			{
    
    
				len=len1;
				flag=1;
				v1=y;
				v2=x;
			}
		}
		if(flag==0)
		{
    
    
			int temp=s;
			while(pre2[temp]!=-1)
			{
    
    
			printf("%d ",temp);
			temp=pre2[temp];				
			}
			printf("%d\n",temp);
			printf("Ticket Not Used\n");
			printf("%d\n",len);			
		}
		else
		{
    
    
			int temp[maxn];
			int i=0;
			temp[i]=v1;

			while(pre1[temp[i]]!=-1)
			{
    
    
				i++;
				temp[i]=pre1[temp[i-1]];
			}				
			for(i;i>=0;i--)
				printf("%d ",temp[i]);
			int temp1;
			temp1=v2;
			while(pre2[temp1]!=-1)
			{
    
    
				printf("%d ",temp1);
				temp1=pre2[temp1];
			}
			printf("%d\n",temp1);				
			//第二行 
			printf("%d\n",v1);
			//第三行 
			printf("%d\n",len);
		}

	}
	
	return 0;
}

Guess you like

Origin blog.csdn.net/alicemh/article/details/105287932