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;
}

 

原文地址:https://www.cnblogs.com/xingxing1024/p/5186009.html