UVA11374_Airport Express

来源:互联网 发布:php抓取访客手机号码 编辑:程序博客网 时间:2024/06/14 13:46

In a small city called Iokh, a train service, Airport-Express,takes residents to the airport more quickly than other transports.There are two types of trains in Airport-Express,the Economy-Xpress and the Commercial-Xpress. Theytravel at different speeds, take different routes and have differentcosts.Jason is going to the airport to meet his friend. He wantsto take the Commercial-Xpress which is supposed to be faster,but he doesn’t have enough money. Luckily he has a ticketfor the Commercial-Xpress which can take him one stationforward. If he used the ticket wisely, he might end up savinga lot of time. However, choosing the best time to use theticket is not easy for him.Jason now seeks your help. The routes of the two typesof trains are given. Please write a program to find the bestroute to the destination. The program should also tell when the ticket should be used.InputThe input consists of several test cases. Consecutive cases are separated by a blank line.The first line of each case contains 3 integers, namely N, S and E (2 ≤ N ≤ 500, 1 ≤ S, E ≤ N),which represent the number of stations, the starting point and where the airport is located respectively.There is an integer M (1 ≤ M ≤ 1000) representing the number of connections between the stationsof the Economy-Xpress. The next M lines give the information of the routes of the Economy-Xpress.Each consists of three integers X, Y and Z (X, Y ≤ N, 1 ≤ Z ≤ 100). This means X and Y areconnected and it takes Z minutes to travel between these two stations.The next line is another integer K (1 ≤ K ≤ 1000) representing the number of connections betweenthe stations of the Commercial-Xpress. The next K lines contain the information of the CommercialXpressin the same format as that of the Economy-Xpress.All connections are bi-directional. You may assume that there is exactly one optimal route to theairport. There might be cases where you MUST use your ticket in order to reach the airport.OutputFor each case, you should first list the number of stations which Jason would visit in order. On thenext line, output ‘Ticket Not Used’ if you decided NOT to use the ticket; otherwise, state the stationwhere Jason should get on the train of Commercial-Xpress. Finally, print the total time for the journeyon the last line. Consecutive sets of output must be separated by a blank line.

再次屎一样的粘贴。

题意就是有一张图,其中有普通线和商业线,给你一次可以坐商务线的机会,求最短路。

因为是一次商务线,所以就枚举每条商务线x->y(注意每条枚举两次)ans=min(st->x)+w+min(y->end)

所以可以看出,以起点和终点分别为起点跑两次dijkstra就可以得出左右的值,枚举w更新ans即可

思路借鉴了一名学长的,用flag分别保存两次dijkstra的结果(其实自己想也能想出来啦,就是太咸鱼了)

#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#include<iostream>#include<vector>using namespace std;typedef long long ll;#define N 505const int inf=0x3f3f3f3f;int mp[N][N];int dis[2][N];bool vis[N];int pre[2][N];int n;void dijkstra(int st,bool flag){memset(vis,0,sizeof(vis));for(int i=1;i<=n;i++){dis[flag][i]=mp[st][i];//printf("%d:%d\n",i,mp[st][i]);pre[flag][i]=st;}dis[flag][st]=0;vis[st]=1;for(int i=1;i<n;i++){int minn=inf;int t=-1;for(int j=1;j<=n;j++){if(!vis[j]&&dis[flag][j]<minn){minn=dis[flag][j];t=j;}}if(t!=-1){vis[t]=1;for(int j=1;j<=n;j++){if(!vis[j]&&dis[flag][j]>dis[flag][t]+mp[t][j]){dis[flag][j]=dis[flag][t]+mp[t][j];pre[flag][j]=t;}}}}}int main(){int tt=0,x,y,w;int st,ed,m,t,q;while(scanf("%d %d %d",&n,&st,&ed)!=EOF){if(tt) printf("\n");++tt;memset(mp,inf,sizeof(mp));scanf("%d",&m);for(int i=0;i<m;i++){scanf("%d %d %d",&x,&y,&w);mp[x][y]=mp[y][x]=w;//printf("%d\n",w);}dijkstra(st,0);//for(int i=1;i<=n;i++)//printf("%d:%d\n",i,dis[0][i]);int upp=-1,down=-1;dijkstra(ed,1);scanf("%d",&q);int temp;int ans=dis[0][ed];//printf("ans:%d\n",ans);for(int i=0;i<q;i++){scanf("%d %d %d",&x,&y,&t);temp=dis[0][x]+dis[1][y]+t;if(temp<ans){upp=x;down=y;ans=temp;}temp=dis[0][y]+dis[1][x]+t;if(temp<ans){upp=y;down=x;ans=temp;}}//printf("%d",ans);if(upp!=-1){   int cur=upp,cnt=0,sav[N];                while(cur!=st)                {                    sav[++cnt]=cur;                    cur=pre[0][cur];                }                sav[++cnt]=st;                for(int i=cnt;i>0;i--)printf("%d ",sav[i]);                cur=down;                while(cur!=ed) printf("%d ",cur),cur=pre[1][cur];                printf("%d\n%d\n%d\n",ed,upp,ans);}else{int u=st;while(u!=ed){printf("%d ",u);u=pre[1][u];}printf("%d\nTicket Not Used\n%d\n",ed,ans);}}return 0;}/*4 1 441 2 12 3 13 4 12 4 212 4 54 1 441 2 12 3 13 4 12 4 212 4 1*/



0 0