UVA 11374 Airport Express

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Caristra/article/details/81866923

UVA 11374 Airport Express

Description:

有两种车票,商务车票和经济车票。商务车票只能买一张,经济车票可以买多张。车票都是双向的。保证商务车会快。现在询问从 S T 的花费的最短时间。
n 500 , m 1000

Solution:

  • 由于 n , m 都比较小,直接从 S T 各跑一遍最短路,最后枚举商务车票即可。
  • 注意,这里是输出路径,需要在第一次跑最短路时记录路径,再递归输出。

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:
此题似乎就是平平谈谈的一道最短路…再枚举一下边,确定最优解。就是一道传统题吧与此专题没什么关系

猜你喜欢

转载自blog.csdn.net/Caristra/article/details/81866923