b1002 All Roads Lead to Rome

题目:https://www.nowcoder.com/pat/5/problem/4315

题意:

回家路线有很多条,现在有n个地点(包括家),每个城市都有幸福感(除了出发城市),现在找出一条最短路,

当路径一样,选择幸福感最大的路线,当幸福感一致,选择平均幸福感最大的路线(不包含出发城市)。

输入

n城市个数,e条边,出发城市

接下来n-1行,每个城市的幸福感

接下来e行,每个城市的距离

输出

最短距离的路线总数,最短距离,幸福感总量,幸福感平均值

最优解路径

输入例子:

6 7 HZH
ROM 100
PKN 40
GDN 55
PRS 95
BLN 80
ROM GDN 1
BLN ROM 1
HZH PKN 1
PRS ROM 2
BLN HZH 2
PKN GDN 1
HZH PRS 1

 

输出例子:

3 3 195 97
HZH->PRS->ROM

代码:

#include <iostream>
#include <bits/stdc++.h>

using namespace std;
const int maxn = 205;
const int INF = 1000000000;

struct node
{
    int v,l;
    node(int _v,int _l):v(_v),l(_l){};
};
vector<node> adj[maxn];
int val[maxn];
int dist[maxn];
int inq[maxn];
map<string,int> cmap;
map<int,string> scmap;
int n,e;
vector<int> pre[maxn];
vector<int> tempPath,path;
int routes,cost,hap,avghap,sum;
void SPFA()
{
    int s=cmap["ROM"];
    for(int i=0;i<=n;i++)
    {
        dist[i]=INF;
    }
    dist[s]=0;
    queue<int> q;
    while(!q.empty()) q.pop();
    inq[s]=1;
    q.push(s);  //千万别忘记压入
    while(!q.empty())
    {
        int u = q.front();
        q.pop();
        inq[u]=0;   //这个千万别少了,防止同一节点多次放入
        for(int i=0;i<adj[u].size();i++)  //领边的大小,而不是n
        {
            int v = adj[u][i].v;
            int l = adj[u][i].l;
            if(v==s) continue;
            if(dist[u]+l<dist[v])
            {
                dist[v]=dist[u]+l;
                pre[v].clear();
                pre[v].push_back(u);
                if(!inq[v])
                {
                    q.push(v);
                    inq[v]=1;
                }
            }
            else if(dist[u]+l==dist[v])
            {
                pre[v].push_back(u);
            }
        }

    }
}

void DFS(int t)
{
    int s = cmap["ROM"];
    if(s==t)
    {
        tempPath.push_back(t); //别忘了最后一个点压入
        routes++;
        int tempHap,tempCost,tempSum;
        tempHap=0;tempCost=0;tempSum=0;
        for(int i=tempPath.size()-1;i>=0;i--)
        {
            tempHap+=val[tempPath[i]];
        }
        tempCost = dist[tempPath[0]];
        tempSum = tempPath.size()-1;
        if(tempHap>hap||((tempHap==hap)&&(tempSum<sum)))
        {
            path=tempPath;
            cost=tempCost;
            hap=tempHap;
            sum=tempSum;
            avghap=hap/sum;
        }
        tempPath.pop_back();//入栈后,一定不要忘了回退出栈,这一点查了好久
    }
    tempPath.push_back(t);
    for(unsigned int i=0;i<pre[t].size();i++)
    {
        DFS(pre[t][i]);
    }
    tempPath.pop_back();
}


int main()
{
    string s1,s2,s3,goal;
    s1.resize(3),s2.resize(3),s3.resize(3),goal.resize(3);
    int value;
    scanf("%d%d%s",&n,&e,&goal[0]);
    cmap.insert(make_pair(goal,0));
    scmap.insert(make_pair(0,goal));
    val[0]=0;  //题目看清,目标节点不计入happiness
    for(int i=1;i<n;i++)
    {
        scanf("%s%d",&s1[0],&value);
        cmap.insert(make_pair(s1,i));
        scmap.insert(make_pair(i,s1));
        val[i]=value;
    }
    int u,v;
    for(int i=0;i<e;i++)
    {
        scanf("%s%s%d",&s2[0],&s3[0],&value);
        if(cmap.find(s2)!=cmap.end())
        {
            u = cmap[s2];
        }
        if(cmap.find(s3)!=cmap.end())
        {
            v = cmap[s3];
        }
        adj[u].push_back(node(v,value));
        adj[v].push_back(node(u,value));
    }
    SPFA();
    routes=0;cost=INF;hap=0;avghap=0;
    DFS(cmap[goal]);
    printf("%d %d %d %d\n",routes,cost,hap,avghap);
    for(unsigned int i=0;i<path.size();i++)
    {
        if(i!=0) printf("->");
        int u = path[i];
        string name = scmap[u];
        printf("%s",name.c_str());
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值