1087 All Roads Lead to Rome (30 分)

这题水的有点蛋疼。

题意

有N个城市,M条无向边。现在需要从某个给定的起始城市出发(除了起始城市外,其他每个城市都有一一个“幸福值”,前往名为“ROM”的城市。给出每条边所需要消耗的花费,求从起始城市出发,到达城市ROM所需要的最少花费,并输出最少花费的路径。如果这样的路径有多条,则选择路径上城市的“幸福值”之和最大的那条。如果路径仍然不唯一,则选择路径上城市的平均幸福值最大的那条。

思路

本题中的边权只有“花费”的概念,因此可以把它作为第一标尺,即把花费理解为距离。除了需要求解从起点到终点的最短距离外,还要求输出最短路径、最短路径条数、路径上的点权之和以及路径上的平均点权。如果有多条最短路径,则选择点权之和最大的一条;若点权之和相同,则选择平均点权最大的一条。

注意点

由于起始顶点的点权没有给出,因此计算平均点权时是不计算起始顶点的,数组num也应当初始化为0。

const int N=210;
unordered_map<string,int> mp;
vector<PII> g[N];
string city[N];
int happy[N];
int dist[N];
bool vis[N];
int f[N],cnt[N],num[N];
int pre[N];
int n,m;

void dijkstra()
{
    memset(dist,0x3f,sizeof dist);
    memset(pre,-1,sizeof pre);
    priority_queue<PII,vector<PII>,greater<PII>> heap;
    dist[1]=0;
    f[1]=0;
    num[1]=0;
    cnt[1]=1;
    heap.push({0,1});

    while(heap.size())
    {
        int t=heap.top().se;
        heap.pop();

        if(vis[t]) continue;
        vis[t]=true;

        for(int i=0;i<g[t].size();i++)
        {
            int j=g[t][i].fi,w=g[t][i].se;
            if(dist[j] > dist[t]+w)
            {
                dist[j]=dist[t]+w;
                f[j]=f[t]+happy[j];
                cnt[j]=cnt[t];
                num[j]=num[t]+1;
                pre[j]=t;
                heap.push({dist[j],j});
            }
            else if(dist[j] == dist[t]+w)
            {
                cnt[j]+=cnt[t];
                if(f[j] < f[t]+happy[j])
                {
                    f[j]=f[t]+happy[j];
                    num[j]=num[t]+1;
                    pre[j]=t;
                }
                else if(f[j] == f[t]+happy[j] && num[j] > num[t]+1)
                {
                    num[j]=num[t]+1;
                    pre[j]=t;
                }
            }
        }
    }
}

void print(int x)
{
    if(x == 1)
    {
        cout<<city[1];
        return;
    }
    print(pre[x]);
    cout<<"->"<<city[x];
}

int main()
{
    cin>>n>>m>>city[1];

    mp[city[1]]=1;
    for(int i=2;i<=n;i++)
    {
        cin>>city[i]>>happy[i];
        mp[city[i]]=i;
    }

    while(m--)
    {
        string a,b;
        int w;
        cin>>a>>b>>w;
        int ta=mp[a],tb=mp[b];
        g[ta].pb({tb,w});
        g[tb].pb({ta,w});
    }

    dijkstra();

    int ed=mp["ROM"];
    cout<<cnt[ed]<<' '<<dist[ed]<<' '<<f[ed]<<' '<<f[ed]/num[ed]<<endl;
    print(ed);
    //system("pause");
    return 0;
}
posted @ 2021-03-01 23:28  Dazzling!  阅读(84)  评论(0编辑  收藏  举报