UVa 11374 Airport Express(优先队列Dijkstra)

从起点,终点分别做两次Dijkatra,算出每一点到起点的最短路程d[i]和到终点的最短路程c[i],枚举K条商业线,作为连接最短路的边,看看d[i]+c[j]+W[i][j]是不是更小了。


代码:

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#include <algorithm>
#include <queue>
#include <vector>
#define INF 1000000000
struct edge{
    int s,t,cost;
    edge(){}
    edge(int s,int t,int c):s(s),t(t),cost(c){}
};
vector<edge> EE;
vector<int> Ec[505];

int d[505];
int c[505];
int N,S,E,M,K;

bool vis[505];
int pd[505];
int pc[505];
void Init(){
    EE.clear();
    for(int i=1;i<=N;i++){
        d[i]=INF;
        c[i]=INF;
        Ec[i].clear();
    }
    memset(pc,0,sizeof(pc));
    memset(pd,0,sizeof(pd));
}

void addedge(int s,int t,int c){
    EE.push_back(edge(s,t,c));
    Ec[s].push_back(EE.size()-1);
}

struct HNode{
    int d,u;
    bool operator <(const HNode &obj)const{
        return d>obj.d;
    }
};

void dij(int s,int d[],int p[]){
    d[s]=0;
    memset(vis,0,sizeof(vis));
    priority_queue<HNode> Q;
    Q.push(HNode{0,s});
    while(!Q.empty()){
        HNode cur=Q.top();
        Q.pop();
        if(vis[cur.u]) continue;
        vis[cur.u]=1;
        for(int i=0;i<Ec[cur.u].size();i++){
            edge &tmp=EE[Ec[cur.u][i]];
            if(d[tmp.t]>d[cur.u]+tmp.cost){
                d[tmp.t]=d[cur.u]+tmp.cost;
                p[tmp.t]=cur.u;
                Q.push(HNode{d[tmp.t],tmp.t});
            }
        }
    }
}

void PrintD(int t){
    if(t==S) printf("%d",S);
    else{
        PrintD(pd[t]);
        printf(" %d",t);
    }
}

void PrintC(int t){
    printf(" %d",t);
    if(t==E) return ;
    PrintC(pc[t]);

}

int main(){
    bool fir=1;
    while(~scanf("%d%d%d",&N,&S,&E)){
        if(fir) fir=0;
        else printf("\n");
        Init();
        scanf("%d",&M);
        for(int i=0;i<M;i++){
            int s,e,cc;
            scanf("%d%d%d",&s,&e,&cc);
            addedge(s,e,cc);
            addedge(e,s,cc);
        }

        dij(S,d,pd);
        dij(E,c,pc);

        int mids=0,midt=0;
        int Min=d[E];
        scanf("%d",&K);
        for(int i=0;i<K;i++){
            int s,e,cost;
            scanf("%d%d%d",&s,&e,&cost);
            if(Min>d[s]+c[e]+cost){
                Min=d[s]+c[e]+cost;
                mids=s;
                midt=e;
            }
            if(Min>d[e]+c[s]+cost){
                Min=d[e]+c[s]+cost;
                mids=e;
                midt=s;
            }
        }

        if(mids==0){
            PrintD(E);
            printf("\n");
            printf("Ticket Not Used\n");
            printf("%d\n",d[E]);
        }
        else {
            PrintD(mids);
            PrintC(midt);
            printf("\n");
            printf("%d\n",mids);
            printf("%d\n",Min);
        }
    }
    return 0;
}


你可能感兴趣的:(dijkstra)