PAT (Advanced Level) Practice 1087 All Roads Lead to Rome (30 分)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Nightmare_ak/article/details/84613342

1、比较函数里要考虑所有维数的优先级
2、每个节点出队列一次,防止相同最短路数量重复计数
因为最短路可能相同的时候,而happiness或average_happiness不同时会把每次记录的num都扔到队列里,那么num就会记重复,为了不重复,所以每个节点只能出队列一次,而且出队列保证是最优的那个节点,所以比较函数里要考虑所有维数的优先级。

#include<cstdio>
#include<map>
#include<vector>
#include<queue>
#include<algorithm>
#include<cstring>
#include<string>
#include<iostream>
using namespace std;

const int N=200+5;

struct Edge
{
    int v,w,next;
}edge[N*N];

struct Node
{
    int u,dis,d,hap;
    bool operator<(const Node& p)const
    {
        if(dis!=p.dis) return dis>p.dis;
        if(hap!=p.hap) return hap<p.hap;
        return d>p.d;
    }
};

int a[N];
int head[N],edgetot;
int dis[N],d[N],hap[N],num[N],pre[N],vis[N];
map<string,int> mp;
map<int,string> rmp;

void addEdge(int u,int v,int w)
{
    edge[edgetot]={v,w,head[u]};
    head[u]=edgetot++;
};

void dijs(int s)
{
    memset(dis,0x3f,sizeof(dis));
    priority_queue<Node> q;
    q.push({s,0,0,0});
    dis[s]=0,d[s]=0,hap[s]=0,num[s]=1;
    while(!q.empty())
    {
        Node u=q.top();
        q.pop();
        if(vis[u.u]) continue;
        vis[u.u]=1;
        for(int i=head[u.u];i!=-1;i=edge[i].next)
        {
            int v=edge[i].v,w=edge[i].w;
            if(dis[u.u]+w<dis[v])
            {
                dis[v]=dis[u.u]+w;
                pre[v]=u.u;
                num[v]=num[u.u];
                hap[v]=hap[u.u]+a[v];
                d[v]=d[u.u]+1;
                q.push({v,dis[v],d[v],hap[v]});
            }
            else if(dis[u.u]+w==dis[v])
            {
                num[v]+=num[u.u];
                if(hap[u.u]+a[v]>hap[v])
                {
                    pre[v]=u.u;
                    hap[v]=hap[u.u]+a[v];
                    d[v]=d[u.u]+1;
                    q.push({v,dis[v],d[v],hap[v]});
                }
                else if(hap[u.u]+a[v]==hap[v])
                {
                    if(d[u.u]+1<d[v])
                    {
                        pre[v]=u.u;
                        d[v]=d[u.u]+1;
                        q.push({v,dis[v],d[v],hap[v]});
                    }
                }
            }
        }
    }
}

void dfs(int u)
{
    if(!pre[u])
    {
        cout<<rmp[u];
        return;
    }
    dfs(pre[u]);
    cout<<"->"<<rmp[u];
}

int main()
{
    int n,k;
    string u;
    cin>>n>>k>>u;
    int cnt=0;
    memset(head,-1,sizeof(head));
    edgetot=0;
    mp[u]=++cnt,rmp[cnt]=u;
    for(int i=1;i<=n-1;i++)
    {
        cin>>u;
        mp[u]=++cnt,rmp[cnt]=u;
        cin>>a[mp[u]];
    }
    while(k--)
    {
        string u,v;
        int w;
        cin>>u>>v>>w;
        addEdge(mp[u],mp[v],w);
        addEdge(mp[v],mp[u],w);
    }
    dijs(1);
    int ed=mp["ROM"];
    printf("%d %d %d %d\n",num[ed],dis[ed],hap[ed],hap[ed]/d[ed]);
    dfs(ed);
    cout<<endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Nightmare_ak/article/details/84613342