Programming thinking week7 assignment B-Airport Express

topic

Today he opened a live broadcast of the trip on Station B, recording his adventures with the magic cat while traveling on the cat. TT sets off from home and prepares to take the Cat Express to Meow Star Airport. The cat cat express line is divided into economic line and commercial line, their speed and price are different. Of course, the commercial line is more expensive than the economic line. TT can usually only take the economic line, but today the magic cat of TT has changed to a commercial line ticket and can take a commercial line. Assuming that the time for TT transfer is negligible, please help TT find the fastest route to Miaoxing Airport, otherwise you will miss the plane!

Input

The input contains multiple sets of data. The first line of each set of data is 3 integers N, S and E (2 ≤ N ≤ 500, 1 ≤ S, E ≤ 100), which is the total number of stations, starting point and end point (that is, the station where the Meowing Airport is located )Numbering.
The next line contains an integer M (1 ≤ M ≤ 1000), which is the number of sections of the economic line.
Next there are M lines, each line of 3 integers X, Y, Z (1 ≤ X, Y ≤ N, 1 ≤ Z ≤ 100), which means that TT can take the economic line to and from station X and station Y, of which one way It takes Z minutes.
The number of road segments in the next line of the commercial line is K (1 ≤ K ≤ 1000).
The next line K is a description of the commercial line segment, the format is the same as the economic line.
All sections are bidirectional, but it may be necessary to use a commercial ticket to reach the airport. Ensure that the optimal solution is unique.

Ouput

For each set of data, output 3 lines. The first line gives the stations (including the start point and the end point) that TT passes through in the order of access, and the second line is the station number of the TT transfer to the commercial line (if the commercial line ticket is not used, output "Ticket Not Used" without quotation marks) ), The third line is the total time spent by TT to the Meow Star Airport.
This question does not ignore extra spaces and tabs, and a newline is output between each set of answers.

Sample Input

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

Sample Ouput

1 2 4
2
5

Ideas

This question gives the starting point and the ending point, and the commercial line can be used at most once (so each commercial line can be enumerated). Enumerate each business line (uvw), calculate the shortest path from the start point to u and the shortest path from v to the end point plus the time w spent by the business line.
Use dijkstra to find the shortest path of a single source without negative edges.
ToThe starting point is the source pointFind the shortest single source, getdis1 []; ToThe end point is the source pointFind the shortest single source, getdis2[]. Enumerate business lines (u, v, w), takemin{dis1[u]+dis2[v]+w, dis1[v]+dis2[u]+w}To get the shortest route along the commercial line. Compare with the shortest route that does not take the commercial line, and take the smaller one.

Dijkstra

Used to solve the figureNo negative edgeofSingle source shortestproblem.

Complexity O ((n + m) logn).

Implementation process:

  • Let s be the source point, dis [a] represents the shortest path from source point s to point a, initializedis[s]=0,dis[i]=inf,wills join the minimum heap
  • Each time the top x of the pile is taken from the pile, all critical edges (xyw) of x are traversed,Compare the size of dis [y] and dis [x] + w. -Slack operation
  • Ifdis[y]>dis[x]+w, The relaxation is successful.Update dis [y]The size ofy join the minimum heap
  • Continue to perform the above operations until the minimum heap is empty, and the resulting dis array is recorded as the shortest short-circuit value of the single source.

Since there are only positive edges in the graph, each point will only be ejected once by the minimum heap, that is, once a point is ejected by the minimum heap, it will not be relaxed again, and the value of dis is the shortest path.

Code

#include <cstdio>
#include <queue>
#include <vector>
#include <cstring>
using namespace std;
struct Edge{
    int to,w,next=-1;
}edge[2005];
const int inf=1e8;
int n,s,e,m,k,head[505],tot,dis1[505],dis2[505],path1[505],path2[505];
bool vis[505];
priority_queue<pair<int,int>> q;

void add(int x,int y,int w){
    edge[++tot].to=y;
    edge[tot].next=head[x];
    edge[tot].w=w;
    head[x]=tot;
}

void dijkstra(int s,int *dis,int *path){
    while(q.size())
        q.pop();
    memset(vis, false, sizeof(vis));
    path[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]=true;
        for(int i=head[x];i!=-1;i=edge[i].next){
            int y=edge[i].to,w=edge[i].w;
            if(dis[y]>dis[x]+w){
                dis[y]=dis[x]+w;
                q.push(make_pair(-dis[y], y));
                path[y]=x;
            }
        }
    }
}

int main() {
    bool firstInput=true;
    while(scanf("%d%d%d",&n,&s,&e)!=EOF){
        for(int i=1;i<=n;i++){
            dis1[i]=inf;
            dis2[i]=inf;
            path1[i]=-1;
            path2[i]=-1;
            head[i]=-1;
        }
        tot=0;
        scanf("%d",&m);
        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, path1);
        dijkstra(e, dis2, path2);
        int u,v,ans=inf;
        scanf("%d",&k);
        for(int i=0;i<k;i++){
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            if(dis1[x]+dis2[y]+z<ans){
                u=x;v=y;
                ans=dis1[x]+dis2[y]+z;
            }
            if(dis1[y]+dis2[x]+z<ans){
                u=y;v=x;
                ans=dis1[y]+dis2[x]+z;
            }
        }
        if(firstInput)
            firstInput=false;
        else
            printf("\n");
        vector<int>vec;
        if(dis1[e]<ans){//不使用商业线
            for(int i=e;i!=s;i=path1[i])
                vec.push_back(i);
            vec.push_back(s);
            for(int i=(int)vec.size()-1;i>0;i--)
                printf("%d ",vec[i]);
            printf("%d\nTicket Not Used\n%d\n",vec[0],dis1[e]);
        }
        else{//使用商业线
            for(int i=u;i!=s;i=path1[i])
                vec.push_back(i);
            vec.push_back(s);
            for(int i=(int)vec.size()-1;i>=0;i--)
                printf("%d ",vec[i]);
            for(int i=v;i!=e;i=path2[i])
                printf("%d ",i);
            printf("%d\n",e);
            printf("%d\n%d\n",u,ans);
        }
    }
}

to sum up

This question started with memset (vis, false, sizeof (vis)) in the main function, and I forgot to initialize it before the second dijkstra, wa for a long time.
Title link

Published 24 original articles · praised 2 · visits 435

Guess you like

Origin blog.csdn.net/weixin_43805228/article/details/105410058