zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    SHELL脚本自动备份Linux系统
    Linux Shell脚本之自动修改IP
    oracle redo日志维护
    Linux运维工程师面试
    angular 的杂碎报错小知识
    angular.run 妙用
    vue的生命周期
    angular +H5 上传图片 与预览图片
    跨域问题解决方案之chrome插件
    js递归
  • 原文地址:https://www.cnblogs.com/fxh0707/p/14466640.html
Copyright © 2011-2022 走看看