UVA 11374 Airport Express
Description:
有两种车票,商务车票和经济车票。商务车票只能买一张,经济车票可以买多张。车票都是双向的。保证商务车会快。现在询问从
S
S
到的花费的最短时间。
n≤500,m≤1000
n
≤
500
,
m
≤
1000
Solution:
- 由于 n n ,都比较小,直接从 S S ,各跑一遍最短路,最后枚举商务车票即可。
- 注意,这里是输出路径,需要在第一次跑最短路时记录路径,再递归输出。
Code:
#include<bits/stdc++.h>
using namespace std;
#define REP(i,f,t)for(int i=(f),i##_end_=(t);i<=i##_end_;i++)
#define SREP(i,f,t)for(int i=(f),i##_end_=(t);i<i##_end_;i++)
#define DREP(i,f,t)for(int i=(f),i##_end_=(t);i>=i##_end_;i--)
#define db double
#define LL long long
#define INF 0x3f3f3f3f
#define MINF 0xc0c0c0c0
#define inf 0x3f3f3f3f3f3f3f
#define Sz(a)sizeof(a)
#define mcl(a,b)memset(a,b,Sz(a))
#define mcp(a,b)memcpy(a,b,Sz(b))
#define pb push_back
#define fi first
#define se second
template<class T>inline bool chkmin(T&x,T y){return y<x?x=y,1:0;}
template<class T>inline bool chkmax(T&x,T y){return x<y?x=y,1:0;}
inline LL Max(LL x,LL y){return x>y?x:y;}
inline LL Min(LL x,LL y){return x<y?x:y;}
typedef pair<int,int>PII;
#define N 502
/*
最短路,记录最短路径,枚举商务票
*/
int n,m,k;
int S,T;
struct node{
int to,cost;
};
vector<node>E[N];
int dis[2][N];
bool vis[N];
queue<int>Q;
int pre[N][2];
void SPFA(int s){
while(!Q.empty())Q.pop();
int op=(s==S)?0:1;
mcl(dis[op],INF);
mcl(vis,0);
Q.push(s);
dis[op][s]=0;
vis[s]=1;
pre[s][op]=s;
while(!Q.empty()){
int x=Q.front();Q.pop();
vis[x]=0;
SREP(i,0,E[x].size()){
int y=E[x][i].to;
if(chkmin(dis[op][y],dis[op][x]+E[x][i].cost)){
pre[y][op]=x;
if(!vis[y]){
vis[y]=1;
Q.push(y);
}
}
}
}
}
void print(int x){
if(pre[x][0]==x){
printf("%d",x);
return;
}
print(pre[x][0]);
printf(" %d",x);
}
void Clear(){
REP(i,1,n)E[i].clear();
mcl(pre,0);
}
int main(){
int cas=0;
while(~scanf("%d%d%d",&n,&S,&T)){
if(cas++)puts("");
Clear();
scanf("%d",&m);
REP(i,1,m){
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
E[a].pb((node){b,c});
E[b].pb((node){a,c});
}
SPFA(S);
SPFA(T);
int ans=dis[0][T],Id1=-1,Id2=-1;
scanf("%d",&k);
REP(i,1,k){
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
if(chkmin(ans,dis[0][a]+dis[1][b]+c))Id1=a,Id2=b;
if(chkmin(ans,dis[0][b]+dis[1][a]+c))Id1=b,Id2=a;
}
if(~Id1){
print(Id1);
for(int i=Id2;i!=T;i=pre[i][1])printf(" %d",i);
printf(" %d\n%d\n",T,Id1);
}
else {
print(T);
printf("\nTicket Not Used\n");
}
printf("%d\n",ans);
}
return 0;
}
Summary:
此题似乎就是平平谈谈的一道最短路…再枚举一下边,确定最优解。就是一道传统题吧与此专题没什么关系…