uva 10537 Toll! Revisited(優先隊列最佳化dijstra及變形)

來源:互聯網
上載者:User

標籤:最短路

Toll! Revisited

大致題意:有兩種節點,一種是大寫字母,一種是小寫字母。首先輸入m條邊,當經過小寫字母時需要付一單位的過路費,當經過大寫字母時,要付當前財務的1/20做過路費。問在起點最少需要帶多少物品使到達終點時還有k個物品。當有多條合格路徑時輸出字典序最小的一個。


思路:已知終點的權值,那麼可以從終點向前推。求終點到起點的最短路徑,然後按字典序列印路徑。

比較難處理的是:向前推時前驅節點的權值計算。列個方程算算就可以了,主要時不能整除的情況。

計算前驅結點dis值的時候,同時記錄(i,j)的邊權值,這是列印路徑的依據。


#include <stdio.h>#include <algorithm>#include <set>#include <map>#include <vector>#include <math.h>#include <string.h>#include <stack>#include <queue>#define LL long long#define _LL __int64using namespace std;const int INF = 0x3f3f3f3f;const int maxm = 1010;const int maxn = 60;struct node{    int v,w;    int next;}edge[maxm];int m;int pre[maxn],cnt;int start,end;LL dis[maxn],p;int vis[maxn];vector <int> ans;void init(){    cnt = 0;    memset(pre,-1,sizeof(pre));    for(int i = 0; i < maxm; i++)        edge[i].w = 0;}void add(int u, int v){    edge[cnt].v = v;    edge[cnt].next = pre[u];    pre[u] = cnt++;}void dijstra(){    priority_queue <pair<LL,int>, vector<pair<LL,int> >, greater<pair<LL,int> > > que;    while(!que.empty()) que.pop();    memset(dis,INF,sizeof(dis));    memset(vis,0,sizeof(vis));    dis[end] = p;    que.push(make_pair(dis[end],end));    while(!que.empty())    {        int u = que.top().second;        que.pop();        if(vis[u]) continue;        vis[u] = 1;        for(int i = pre[u]; i != -1; i = edge[i].next) //鬆弛相鄰節點        {            if(vis[edge[i].v]) continue;            int v = edge[i].v;            if(u < 26)            {                //計算前驅結點的權值,判斷是否整除,若不整除,嘗試加1繼續判斷                if(dis[u]%19 == 0)                {                    if(dis[v] > dis[u]/19*20)                    {                        dis[v] = dis[u]/19*20;                        edge[i].w = edge[i^1].w = dis[v]-dis[u];                        que.push(make_pair(dis[v],v));                    }                }                else if( (dis[u]+1)%19 )                {                    if(dis[v] > (dis[u]+1)*20/19)                    {                        dis[v] = (dis[u]+1)*20/19;                        edge[i].w = edge[i^1].w = dis[v]-dis[u];                        que.push(make_pair(dis[v],v));                    }                }                else                {                    if(dis[v] > (dis[u]+1)*20/19-1 )                    {                        dis[v] = (dis[u]+1)*20/19-1;                        edge[i].w = edge[i^1].w = dis[v]-dis[u];                        que.push(make_pair(dis[v],v));                    }                }            }            else            {                if(dis[v] > dis[u]+1)                {                    dis[v] = dis[u]+1;                    edge[i].w = edge[i^1].w = 1;                    que.push(make_pair(dis[v],v));                }            }        }    }}void solve(){    ans.clear();    int now;    now = start;    ans.push_back(now);    while(now != end)    {        int tmp = 1<<6;        for(int i = pre[now]; i != -1; i = edge[i].next)        {            int v = edge[i].v;            //因為輸出字典序最小的,所以求出滿足dis[now] - dis[v] == edge[i].w中最小的v            if(dis[now] - dis[v] == edge[i].w && v < tmp)            {                tmp = v;            }        }        ans.push_back(tmp);        now = tmp;    }    printf("%c",ans[0]+‘A‘);    for(int i = 1; i < (int)ans.size(); i++)        printf("-%c",ans[i]+‘A‘);    printf("\n");}int main(){    int item = 1;    char t1,t2;    while(~scanf("%d",&m))    {        if(m == -1) break;        init();        getchar();        for(int i = 0; i < m; i++)        {            scanf("%c %c",&t1,&t2);            getchar();            add(t1-‘A‘,t2-‘A‘);            add(t2-‘A‘,t1-‘A‘);        }        scanf("%lld %c %c",&p,&t1,&t2);        start = t1-‘A‘;        end = t2-‘A‘;        dijstra();        printf("Case %d:\n",item++);        printf("%lld\n",dis[start]);        solve();    }    return 0;}


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.