TT's travel diary

Title: TT's travel diary
Title: As we all know, TT has a magic cat.
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).
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 commercial tickets to reach the airport. Ensure that the optimal solution is unique.

Output:
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. 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 the extra spaces and tabs, and a newline should be output between each set of answers

Sample:
Input sample
4 1 4
4
1 2 2
1 3 3
2 4 4
3 4 5
1
2 4 3
Output sample
1 2 4
2
5

Problem-solving ideas: First of all, if there is no business line, it is a simple shortest source path problem; with a business line, it becomes complicated; the method used here is:
Insert picture description here
double-layer graph structure, the upper and lower points are the same, and there are more in the middle Path; I can first run the shortest path from the starting point as the origin, and then run the shortest path again from the starting point; then enumerate all the commercial lines x, y, z; from the starting point to x or y, from the end point to y or x, then add a z and compare it with the original from the start to the end;

Code:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<vector>
#include<queue>
#define Max 1000000000
using namespace std;
struct node
{
    int to;
    int next;
    int v;
}e[20005];
int n,a,b,m,k,ticket=-1;
int d1[20005],color1[20005],p1[20005]={0};
int d2[20005],color2[20005],p2[20005]={0};
int head[2005],tot=0;
int flag=0;
void add(int x,int y,int z)
{
    e[++tot].to=y;
    e[tot].next=head[x];
    e[tot].v=z;
    head[x]=tot;
}
void dij1()//堆优化+前向星的dij
{
    for(int i=1;i<=n;i++)
    {
        d1[i]=Max;
    }
    d1[a]=0;
    pair<int,int> s=make_pair(0,a);
    priority_queue<pair<int,int> ,vector<pair<int,int> >,greater<pair<int,int> > > q;
    q.push(s);
    int t;
    while(!q.empty())
    {
        pair<int,int> u=q.top();
        q.pop();
        int u1=u.first,u2=u.second;
        color1[u2]=1;
        for(int i=head[u2];i;i=e[i].next)
        {
            int j=e[i].to,w=e[i].v;
            if(color1[j]!=1)
            {
                if(d1[j]>d1[u2]+w)
                {
                    d1[j]=d1[u2]+w;
                    q.push(make_pair(d1[j],j));
                    p1[j]=u2;
                }
            }
        }
    }
}
void dij2()
{
    for(int i=1;i<=n;i++)
    {
        d2[i]=Max;
    }
    d2[b]=0;
    pair<int,int> s=make_pair(0,b);
    priority_queue<pair<int,int> ,vector<pair<int,int> >,greater<pair<int,int> > > q;
    q.push(s);
    int t;
    while(!q.empty())
    {
        pair<int,int> u=q.top();
        q.pop();
        int u1=u.first,u2=u.second;
        color2[u2]=1;
        for(int i=head[u2];i;i=e[i].next)
        {
            int j=e[i].to,w=e[i].v;
            if(color2[j]!=1)
            {
                if(d2[j]>d2[u2]+w)
                {
                    d2[j]=d2[u2]+w;
                    q.push(make_pair(d2[j],j));
                    p2[j]=u2;
                }
            }
        }
    }
}
int main()
{
    while(scanf("%d%d%d",&n,&a,&b)!=EOF)
    {
        if(!flag) flag=true;//这个是格式问题,每组答案有个空行,最后不能有空行
        else printf("\n");
        tot=0;
        memset(head,0,sizeof(head));
        memset(color1,0,sizeof(color1));
        memset(color2,0,sizeof(color2));
        memset(p1,0,sizeof(p1));
        memset(p2,0,sizeof(p2));
        scanf("%d",&m);
        int x,y,z;
        for(int i=0;i<m;i++)
        {
            scanf("%d%d%d",&x,&y,&z);
            add(x,y,z);
            add(y,x,z);
        }
        dij1();//跑两遍dij
        dij2();
        int ans=d1[b];
        scanf("%d",&k);
        int t1,t2;
        for(int i=0;i<k;i++)
        {
            scanf("%d%d%d",&x,&y,&z);
            if(d1[x]+d2[y]<d1[y]+d2[x])
            {
                if(d1[x]+d2[y]+z<ans)
                {
                    ticket=x;
                    ans=d1[x]+d2[y]+z;
                    t1=x,t2=y;
                }
            }else
            {
                if(d1[y]+d2[x]+z<ans)
                {
                    ticket=y;
                    ans=d1[y]+d2[x]+z;
                    t1=y,t2=x;
                }
            }
        }
        vector<int> v;//这是我用的路径记录,记录的是儿子节点
        if(ans==d1[b])
        {
            int tt=b;
            while(tt!=a)
            {
                v.push_back(tt);
                tt=p1[tt];
            }
            v.push_back(a);
            for(int i=v.size()-1;i>=0;i--)
            {
                if(i+1-v.size()){printf(" ");}
                printf("%d",v[i]);
            }
        }
        else
        {
            int tt=t1;
            while(tt!=a)
            {
                v.push_back(tt);
                tt=p1[tt];
            }
            v.push_back(a);
            tt=t2;
            while(tt!=b)
            {
                v.insert(v.begin(),tt);
                tt=p2[tt];
            }
            v.insert(v.begin(),b);
            for(int i=v.size()-1;i>=0;i--)
            {
                if(i+1-v.size()){printf(" ");}
                printf("%d",v[i]);
            }
        }
        if(ans==d1[b])//特判一下
        {
            printf("\nTicket Not Used\n%d\n",ans);
        }else
            printf("\n%d\n%d\n",ticket,ans);
    }
}
PGZ
Published 34 original articles · praised 0 · visits 867

Guess you like

Origin blog.csdn.net/qq_43653717/article/details/105291549