zoukankan      html  css  js  c++  java
  • The Toll! Revisited UVA

    给定图G=VEG=(V,E),VV中有两类点,一类点(AA类)在进入时要缴纳1的费用,另一类点(BB类)在进入时要缴纳当前携带金额的1/20(不足20的部分按20算) 
    已知起点为SS,终点为TT,希望在到达TT时能够拥有PP的金额,问一开始在SS最少要携带多少金额,并求出路径(若有多条,输出字典序最小的) 
    SS离开时不需要缴费,进入TT时需要缴费

    倒序找最短路  d[i] 表示从i到终点需要的最少的金额 在更新d的时候 分两种情况 

    #include <map>
    #include <cmath>
    #include <queue>
    #include <vector>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    const int N = 10500;
    const long long Inf = (1LL<<61);
    int head[N];
    int vis[255];
    int cnt;
    char to[255];
    int n, m;
    long long d[N];
    bool inq[N];
    int p[N];
    struct Edge{
        int v, w, next;
    }edges[N*5];
    
    void add(int u ,int v, int w)
    {
        edges[cnt].v = v;
        edges[cnt].w = w;
        edges[cnt].next = head[u];
        head[u] = cnt++;
    }
    
    void init()
    {
        memset(head, -1, sizeof(head));
        cnt = 0;
    }
    
    void print(int u){
        if( p[u]==-1 ){
            printf("%c
    ", to[u] );
            return ;
        }
        printf("%c-", to[u] );
        print(p[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=head[u]; i!=-1; i=edges[i].next ){
                Edge e=edges[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[p[e.v]] ){  //如果相等 则判断字典序
                    d[e.v]=nd;
                    p[e.v]=u;
                    if( !inq[e.v] ){
                        inq[e.v]=1;
                        Q.push(e.v);
                    }
                }
            }
        }
    }
    
    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 ){
            init();
            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]];
                add(u,v,a[0]<'a');
                add(v,u,b[0]<'a');
            }
            long long vl;
            scanf("%lld%s%s", &vl, a, b );
            int u=vis[a[0]], v=vis[b[0]];
            spfa(v,vl);
            printf("Case %d:
    ", ++kas);
            printf("%lld
    ", d[u]);
            print(u);
        }
    }
    自己选择的路,跪着也要走完。朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。
  • 相关阅读:
    POJ_1485_dp
    POJ_1376_bfs
    [noi1994]海盗
    [noi1755]Trie
    [luogu3733]八纵八横
    [noi1774]array
    [noi1773]function
    [noi1754]SA
    [noi1779]D
    [bzoj4873]寿司餐厅
  • 原文地址:https://www.cnblogs.com/WTSRUVF/p/9407654.html
Copyright © 2011-2022 走看看