PAT (Advanced Level) 1087 All Roads Lead to Rome

题解

    最短路径经典题型。套最短路的板子再加上额外的要求就可以了(说起来好简单)。SPFA也行,Dijkstra也可以。这里我用的是SPFA。因为题目要求,将地名和其对应的数字用map映射一下,这样方便处理。

         same[i]代表到达地点 i 有几种路径;

         dist[i]代表从起点到地点 i 的最短距离;

         happy[i]代表从起点到地点 i 的幸福值;

         cnt[i]代表从起点到地点 i 需要经过几个城市;

         ans[i]代表从哪个地点到达了地点 i ;

代码

#include<bits/stdc++.h>
using namespace std;
const int maxn=250,inf=0x3fffffff;
struct node
{
    int v,w;
    node(int a,int b)
    {v=a;w=b;}
};
int same[maxn]={0,1},dist[maxn],vis[maxn],happy[maxn],cnt[maxn],ans[maxn];
int value[maxn],N,K;
map<string,int> smapi;
map<int,string> imaps;
vector<node> edge[maxn];
void spfa(int s);
void print(int p);
int main() 
{
    string str_s,str,u,v;
    int i,w,end;
    scanf("%d%d",&N,&K);
    cin>>str_s;
    smapi[str_s]=1; imaps[1]=str_s;

    for(i=2;i<=N;i++)
    {
        cin>>str>>w;
        if(str=="ROM") end=i;
        smapi[str]=i; imaps[i]=str;
        value[i]=w;
    }

    for(i=0;i<K;i++)
    {
        cin>>u>>v>>w;
        edge[smapi[u]].push_back(node(smapi[v],w));
        edge[smapi[v]].push_back(node(smapi[u],w));
    }

    spfa(1);

    printf("%d %d %d %d\n",same[end],dist[end],happy[end],happy[end]/cnt[end]);
    print(ans[end]);
    printf("ROM");

    system("pause");
    return 0;
}
void print(int p)
{
    if(p==0) return ;
    print(ans[p]);
    printf("%s->",imaps[p].c_str());
}
void spfa(int s)
{
    queue<int> que;
    int p,i,v,w;

    fill(dist+2,dist+maxn,inf);
    que.push(s);
    while(!que.empty())
    {
        p=que.front();que.pop();
        vis[p]=0;
        for(i=0;i<edge[p].size();i++)
        {
            v=edge[p][i].v;
            w=edge[p][i].w;

            if(dist[v]>dist[p]+w)
            {
                dist[v]=dist[p]+w;
                happy[v]=happy[p]+value[v];
                cnt[v]=cnt[p]+1;
                ans[v]=p;
                same[v]=same[p];
                if(!vis[v])
                {
                    que.push(v);
                    vis[v]=1;
                }
            }
            else if(dist[v]==dist[p]+w)
            {
                same[v]+=same[p];
                if(happy[v]<happy[p]+value[v])
                {
                    happy[v]=happy[p]+value[v];
                    cnt[v]=cnt[p]+1;
                    ans[v]=p;
                }
                else if(happy[p]+value[v]==happy[v])
                {
                    if(cnt[v]>cnt[p]+1)
                    {
                        cnt[v]=cnt[p]+1;
                        ans[v]=p;
                    }
                }
            }
        }
    }
}
posted @ 2020-01-23 23:41  Vivid-BinGo  阅读(155)  评论(0编辑  收藏  举报