• 1002 All Roads Lead to Rome


     

    这个题就是求最短路径, 然而还有一些限制条件就是最短路一样的时候顶点的欢乐值要最大, 欢乐值一样的时候路径上顶点的个数要最小(不包括源点), 另外要顺带求出最短路径的个数。 实现的时候我们可以用优先队列来优化dijkstra算法, 每更新一个数值其他的也要相应的更新, 另外在求解路径个数的时候假设我们以rout[u]表示最短到达u的最短路的个数, 那么对于d[v] > d[u] + c的时候就有rout[v] = rout[u], d[v]==d[u]+c就有rout[v]+=rout[u];代码如下:

     

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <map>
    #include <string>
    #include <vector>
    #include <iostream>
    #include <queue>
    
    using namespace std;
    int N, M;
    int vm[210];
    map<string, int> str2int;
    vector<string> int2str;
    
    struct edge{ int to, c; };
    vector<edge> G[210];
    bool vis[210];
    int rout[210];           //路径个数
    int d[210];              //最短路径
    int hpy[210];            //欢乐值
    int geshu[210];          //到v的顶点的个数
    int pre[210];
    struct Dij
    {
        int u, c;
        bool operator < (const Dij&r) const
        {
            return c > r.c;
        }
    };
    void dijkstra()
    {
        memset(vis, 0, sizeof(vis));
        memset(d, 0x3f, sizeof(d));
        memset(rout, 0, sizeof(rout));
        memset(hpy, -1, sizeof(hpy));
        memset(geshu, 0x3f, sizeof(geshu));
        d[0] = 0; rout[0]=1; hpy[0]=0; geshu[0]=0;
        pre[0] = -1;
        priority_queue<Dij> que;
        que.push((Dij){0, 0});
        while(!que.empty())
        {
            Dij tp = que.top(); que.pop();
            int u = tp.u;
            if(vis[u]) continue;
            vis[u] = 1;
            for(int i=0; i<G[u].size(); i++)
            {
                int v = G[u][i].to, c = G[u][i].c;
                if(d[v]>d[u]+c)
                {
                    d[v] = d[u]+c;
                    que.push((Dij){v, d[v]});
                    rout[v] = rout[u];
                    hpy[v] = hpy[u]+vm[v];
                    geshu[v] = geshu[u]+1;
                    pre[v] = u;
                }
                else if(d[v]==d[u]+c && hpy[u]+vm[v]>hpy[v])
                {
                    rout[v] += rout[u];
                    hpy[v] = hpy[u]+vm[v];
                    geshu[v] = geshu[u]+1;
                    pre[v] = u;
                }
                else if(d[v]==d[u]+c&&hpy[u]+vm[v]==hpy[v]&&geshu[u]+1<geshu[v])
                {
                    rout[v] += rout[u];
                    geshu[v] = geshu[u]+1;
                    pre[v] = u;
                }
                else if(d[v]==d[u]+c)
                    rout[v] += rout[u];
    
            }
        }
    }
    int main()
    {
        cin>>N>>M;
        string str; cin>>str;
        str2int[str] = 0; int2str.push_back(str); vm[0] = 0;
        for(int i=1; i<N; i++)
        {
            string uu; int t;
            cin>>uu>>t;
            str2int[uu] = i; int2str.push_back(uu);
            vm[i] = t;
        }
        for(int i=0; i<M; i++)
        {
            string uu, vv; int t;
            int u, v;
            cin>>uu>>vv>>t;
            u = str2int[uu]; v = str2int[vv];
            G[u].push_back((edge){v, t});
            G[v].push_back((edge){u, t});
        }
        dijkstra();
        int t = str2int["ROM"];
        cout<<rout[t]<<' '<<d[t]<<' '<<hpy[t]<<' '<<hpy[t]/geshu[t]<<endl;
        vector<int> e;
        int u = t;
        while(u!=-1)
        {
            e.push_back(u);
            u = pre[u];
        }
        for(int i=e.size()-1; i>=0; i--)
        {
            if(i==0) cout<<int2str[e[i]]<<endl;
            else cout<<int2str[e[i]]<<"->";
        }
        return 0;
    }

     

  • 相关阅读:
    Android拍照、摄像方向旋转的问题 代码具体解释
    Java 实现桥接(Bridge)模式
    C++标准I/O库:iostream, fstream, sstringstream
    Android 使用 DownloadManager 管理系统下载任务的方法
    JavaScript提高:005:ASP.NET使用easyUI TABS标签显示问题
    使用c++的cocos2d-x-3.0rc1程序公布apk
    UVA 146 ID Codes(下一个排列)
    C/C++:C++伪函数
    开源项目AndroidUtil-採用Fragment实现TabHost
    系统编程是什么
  • 原文地址:https://www.cnblogs.com/xingxing1024/p/5186009.html
Copyright © 2020-2023  润新知