Dijkstra(低价空中旅行,LA 3561)

来源:互联网 发布:上海东京飞机票知乎 编辑:程序博客网 时间:2024/05/22 10:47

任何最短路的本质都是状态的最短路。其中涉及状态的定义以及状态的转移。


当然你也可以用图论对状态建模,然后再跑普通的Dijkstra。


代码

#include<bits/stdc++.h>#define rep(i,a,b) for(int i=a;i<=b;i++)using namespace std;const int maxn = 5000;const int inf = 0x3f3f3f3f;struct Edge{    int from,to,dist,id;};struct HeapNode{    int d,u;    bool operator < (const HeapNode& rhs) const    {        return d>rhs.d;    }};struct Dijkstra{    int n,m;    vector<Edge>edges;    vector<int>G[maxn];    int d[maxn],done[maxn],p[maxn];    void init(int n)    {        this->n=n;        edges.clear();        rep(i,0,n-1) G[i].clear();    }    void add(int u,int v,int dist,int id)    {        edges.push_back((Edge){u,v,dist,id});        m=edges.size();        G[u].push_back(m-1);    }    void dijkstra(int s)    {        rep(i,0,n-1)        {            d[i]=inf;            done[i]=0;        }        d[s]=0;        priority_queue<HeapNode>Q;        Q.push((HeapNode){0,s});        while(!Q.empty())        {            HeapNode x=Q.top();Q.pop();            int u=x.u;            if(done[u]) continue;            done[u]=1;            for(unsigned int i=0;i<G[u].size();i++)            {                Edge& e=edges[G[u][i]];                if(d[e.to]>d[e.from]+e.dist)                {                    d[e.to]=d[e.from]+e.dist;                    p[e.to]=G[u][i];                    Q.push((HeapNode){d[e.to],e.to});                }            }        }    }    void debug()    {        puts("debug");        for(unsigned int i=0;i<edges.size();i++)        {            Edge& e=edges[i];            printf("%d %d %d\n",e.from,e.to,e.dist);        }        puts("debug");    }};int NT,NI;int nt[22][12],ni[22][12];int ntn[22],nin[22];int pri[22];Dijkstra DIJ;int kase;map<int,int>ID;int N;vector<int>G[500];void print(int a,int b,int c,int s,int t){    printf("Case %d, Trip %d: Cost = %d\n",a,b,c);    stack<int>S;    while(s!=t)    {        Edge& e=DIJ.edges[DIJ.p[t]];        S.push(e.id);        t=e.from;    }    printf("  Tickets used:");    while(!S.empty())    {        printf(" %d",S.top()+1);        S.pop();    }    puts("");}int main(){    int tp;    while(scanf("%d",&NT)==1&&NT)    {        N=0;        ++kase;        ID.clear();        rep(i,0,NT-1)        {            scanf("%d %d",pri+i,ntn+i);            rep(j,0,ntn[i]-1)            {                scanf("%d",&tp);                if(!ID.count(tp)) ID[tp]=N++;                nt[i][j]=ID[tp];            }        }        scanf("%d",&NI);        rep(i,0,NI-1)        {            scanf("%d",nin+i);            rep(j,0,nin[i]-1)            {                scanf("%d",&tp);                ni[i][j]=ID[tp];            }        }        rep(T,0,NI-1)        {            rep(i,0,N-1) G[i].clear();            rep(i,0,NT-1) G[nt[i][0]].push_back(i);            DIJ.init((nin[T]+1)*N);            rep(i,0,nin[T]-1) rep(j,0,N-1) rep(u,0,(int)G[j].size()-1)            {                int k=i;                rep(v,0,ntn[G[j][u]]-1)                {                    if(k>=nin[T]) break;                    if(ni[T][k]==nt[G[j][u]][v]) k++;                    DIJ.add(i*N+j,k*N+nt[G[j][u]][v],pri[G[j][u]],G[j][u]);                    //printf("%d %d %d %d %d\n",i,j,k,nt[G[j][u]][v],pri[G[j][u]]);                    //printf("%d %d %d\n",i*nin[T]+j,k*nin[T]+nt[G[j][u]][v],pri[G[j][u]]);                }            }            //DIJ.debug();            DIJ.dijkstra(ni[T][0]);            print(kase,T+1,DIJ.d[nin[T]*N+ni[T][nin[T]-1]],ni[T][0],nin[T]*N+ni[T][nin[T]-1]);        }    }    return 0;}


0 0