B-dijkstra-TT's travel diary

Topic:

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).

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.

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

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
25

My Solution:

The introduction of the business line in this question complicates the problem. If there is no business line, the problem becomes the shortest path problem in the simple graph problem.

We found that after joining the commercial line, there are two methods, the shortest path contains a commercial line or does not contain a commercial line.

For cases that do not include commercial lines, we can find the shortest route.

For cases involving business lines, because only one business line is taken, we can enumerate the situation of each business line and then take the minimum.

Next, how to find a short circuit for the problem of taking (one) commercial line?

Run the shortest route from the start point and the end point respectively, and then take the minimum value twice

min (dis1[u]+dis2[v]+w , dis1[v]+dis2[u]+w ) 

Finally, merge the above situations, and take the smallest one!

 
 
  1 #include<iostream>
  2 #include<string.h>
  3 #include<algorithm> 
  4 using namespace std;
  5 const int maxn=1000010;
  6 int n,m,k,s,e,tot,ans=10000000,sum;
  7 int head[maxn],dis1[maxn],dis2[maxn];
  8 int pre1[maxn],pre2[maxn];
  9 int p[maxn],a[maxn];
 10 bool flag[maxn];
 11 int ans_u,ans_v,ans_w;
 12 struct node
 13 {
 14     int v;
 15     int w;
 16     int next;
 17 }e1[maxn];
 18 void add_edge(int u,int v,int w)
 19 {
 20     e1[++tot].v=v;
 21     e1[tot].w=w;
 22     e1[tot].next=head[u];
 23     head[u]=tot;
 24 }
 25 
 26 void dijkstra(int u,int *dis,int *pre)
 27 {
 28     memset(flag,0,sizeof(flag));
 29     for(int i=1;i<=n;i++)
 30     dis[i]=maxn;
 31     dis[u]=0;
 32     for(int i=1;i<=n;i++)
 33     {
 34         int k=0,minn=maxn;
 35         for(int j=1;j<=n;j++)
 36         if(!flag[j]&&dis[j]<minn)
 37         {
 38             minn=dis[j];
 39             k=j;
 40         }
 41         flag[k]=1;
 42         for(int j=head[k];j;j=e1[j].next)
 43         if(!flag[e1[j].v]&&dis[e1[j].v]>dis[k]+e1[j].w) //松弛 
 44         {
 45             dis[e1[j].v]=dis[k]+e1[j].w;
 46             pre[e1[j].v]=k;
 47         }
 48     }
 49 }
 50 int main()
 51 {
 52     int x,y,z,u,v,w;
 53     cin>>n>>s>>e; 
 54     while(1)
 55     {
 56         memset(flag,0,sizeof(flag));
 57         memset(pre1,0,sizeof(pre1));
 58         memset(pre2,0,sizeof(pre2));
 59         memset(head,0,sizeof(head));
 60         memset(a,0,sizeof(a));
 61         tot=0;
 62         cin>>m;
 63         ans_u=0;sum=0;
 64         for(int i=1;i<=m;i++)
 65         {
 66             cin>>x>>y>>z;
 67             add_edge(x,y,z);
 68             add_edge(y,x,z);
 69         }
 70         
 71         dijkstra(s,dis1,pre1) ;
 72         dijkstra(e,dis2,pre2) ;
 73         
 74         cin>>k;
 75         int ans=dis1[e];
 76         for(int i=1;i<=k;i++)
 77         {
 78             cin>>u>>v>>w;
 79             if(dis1[u]+dis2[v]+w<ans)
 80             {
 81                 ans=dis1[u]+dis2[v]+w;
 82                 ans_u=u;
 83                 ans_v=v;
 84             }
 85             if(dis2[u]+dis1[v]+w<ans)//再次更新 
86              {
 87                  ans = dis2 [u] + dis1 [v] + w;
 88                  ans_u = v;
 89                  ans_v = u;
 90              }
 91          }
 92          int tmp;
 93          if (ans_u == 0 ) // Business line 
94 is  not required         {
 95              tmp = e;
 96              while (tmp)
 97              {
 98                  a [++ sum] = tmp;
 99                  if (tmp == s) break;
100                 tmp=pre1[tmp];
101             }
102             for(int i=sum;i>=2;i--) cout<<a[i]<<" ";
103             cout<<a[1]<<endl;
104             cout<<"Ticket Not Used"<<endl<<ans<<endl;
105         }
106         else//需要商务线 
107         {
108             tmp=ans_v;
109             while(tmp)
110             {
111                 a[++sum]=tmp;
112                 if(tmp==e) break;
113                 tmp=pre2[tmp];
114             }
115             for(int i=1;i<=sum/2;i++)
116             swap(a[i],a[sum-i+1]);
117             tmp=ans_u;
118             while(tmp)
119             {
120                 a[++sum]=tmp;
121                 if(tmp==s) break;
122                 tmp=pre1[tmp];
123             }
124             for(int i=sum;i>=2;i--) cout<<a[i]<<" ";
125             cout<<a[1]<<endl;
126             cout<<ans_u<<endl<<ans<<endl;
127         }
128         
129         if(cin>>n>>s>>e)
130             cout<<endl;     //每个输出换行 
131         else 
132             break;
133     }
134     return 0;
135 }
 
 

 

 

 

Guess you like

Origin www.cnblogs.com/liuzhuan-xingyun/p/12717899.html