UVA10537[The Toll! Revisited] dijkstra/spfa 反向建图

来源:互联网 发布:xio网络用语什么意思 编辑:程序博客网 时间:2024/05/21 18:42

题目链接


题意:给定一个无向图,大写字母是城市,小写字母是村庄,经过城市交过路费为当前货物的%5,路过村庄固定交1,给定起点终点和到目标地点要剩下的货物,问最少要带多少货物上路,并输出路径,如果有多种方案,要求字典序最小


solution:反向建图, d[i]表示从i到终点需要的数量。

#include <map>#include <cmath>#include <queue>#include <vector> #include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;const int N = 105;const long long Inf = (1LL<<61);struct Edge{    int u, v, w;    Edge(int u, int v, int w):u(u),v(v),w(w){}}; struct HeapNode{    long long d;int u;    bool operator<(const HeapNode& rhs) const{        return d>rhs.d;    }};char to[255];struct Dijkstra{    int n, m;    long long d[N];    bool done[N];    vector<Edge> edges;    vector<int> G[N];    int p[N];    void init(int n){        this->n=n;        for ( int i=0; i<n; i++ ) G[i].clear();        edges.clear();     }    void addeage(int u, int v, int w){        edges.push_back((Edge){u,v,w});        m=edges.size();        G[u].push_back(m-1);    }    void print(int u){        if( p[u]==-1 ){            printf("%c\n", to[u]);            return;        }        printf("%c-", to[u] );        print(edges[p[u]].u);    }    void dijkstra(int s, long long vl){        for ( int i=0; i<n; i++ ) d[i]=Inf, done[i]=0;        d[s]=vl;        p[s]=-1;        priority_queue<HeapNode> Q;        Q.push((HeapNode){vl,s});        while( !Q.empty() ){            HeapNode x=Q.top(); Q.pop();            int u=x.u;            if( done[u] ) continue;            done[u]=1;            for ( int i=0; i<G[u].size(); i++ ){                Edge& e=edges[G[u][i]];                long long nd;                if( e.w ) nd= (long long) ceil(d[u]*1.0/19*20);                else nd=d[u]+1;                if( d[e.v]>nd || d[e.v]==nd && to[u]<to[edges[p[e.v]].u] ){                    d[e.v]=nd;                    p[e.v]=G[u][i];                    Q.push((HeapNode){d[e.v],e.v});                }            }        }    }};struct SPFA{    int n, m;    long long d[N];    bool inq[N];    int p[N];    vector<Edge> edges;    vector<int> G[N];    void init(int n){        this->n=n;        for ( int i=0; i<n; i++ ) G[i].clear();        edges.clear();    }    void addeage(int u, int v, int w){        edges.push_back((Edge){u,v,w});        m=edges.size();        G[u].push_back(m-1);    }    void print(int u){        if( p[u]==-1 ){            printf("%c\n", to[u] );            return ;        }        printf("%c-", to[u] );        print(edges[p[u]].u);    }    void spfa(int s, long long vl){        for ( int i=0; i<n; i++ ) d[i]=Inf, inq[i]=0;        d[s]=vl;        p[s]=-1;        queue<int> Q;        Q.push(s);        while( !Q.empty() ){            int u=Q.front(); Q.pop();            inq[u]=0;            for ( int i=0; i<G[u].size(); i++ ){                Edge& e=edges[G[u][i]];                long long nd;                if( e.w ) nd=(long long) ceil(d[u]*1.0/19*20);                else nd=d[u]+1;                if( d[e.v]>nd || d[e.v]==nd && to[u]<to[edges[p[e.v]].u] ){                    d[e.v]=nd;                    p[e.v]=G[u][i];                    if( !inq[e.v] ){                        inq[e.v]=1;                        Q.push(e.v);                    }                }            }        }    }};SPFA D;int vis[255];int main(){    for ( int i=0; i<26; i++ ) {        vis['a'+i]=i+26; to[i+26]='a'+i;        vis['A'+i]=i; to[i]='A'+i;    }    int n, m, kas=0;    while( scanf("%d", &m ) == 1 && m!=-1 ){        D.init(52);        char a[2], b[2];        for ( int i=1; i<=m; i++ ){            scanf("%s%s", a, b );            int u=vis[a[0]], v=vis[b[0]];            D.addeage(u,v,a[0]<'a');            D.addeage(v,u,b[0]<'a');        }        long long vl;        scanf("%lld%s%s", &vl, a, b );        int u=vis[a[0]], v=vis[b[0]];        D.spfa(v,vl);        printf("Case %d:\n", ++kas);          printf("%lld\n", D.d[u]);          D.print(u);    }}
原创粉丝点击