1087 All Roads Lead to Rome (30分)

1087 All Roads Lead to Rome (30分)

we are supposed to find the route with the least cost. If such a route is not unique, the one with the maximum happiness will be recommanded. If such a route is still not unique, then we output the one with the maximum average happiness

选择用DFS+Dijkstra算法,Dijkstra获取最短路径,再有DFS得到解。(最大平均幸福度,不把起点算在内)

AC代码

#include <iostream>
#include <vector>
#include <cstdio>
#include <map>
using namespace std;
const int maxn=220;
const int INF=0x3fffffff;
int n,k;char _begin[4];
map<string,int> mp;
map<int,string> IntToString;
vector<int> pre[maxn];
int weight[maxn];
struct Node{
    int v,dis;
    Node(int v,int dis):v(v),dis(dis){
    }
};
vector<Node> G[maxn];
int d[maxn];
bool vis[maxn];
vector<int> path,temp;
int sum_value=0;
double a_value=0;
int cnt=0;
void DFS(int u){
    if(u==0){
        cnt++;
        int sv=0;
        for(int i=0;i<temp.size();i++){
           sv+=weight[temp[i]];
        }
        double av=(double)sv/(temp.size()-1);
        if(sv>sum_value){
            sum_value=sv;
            a_value=av;
            path=temp;
        }if(sv==sum_value&&av>a_value){
            a_value=av;
            path=temp;
        }
        return;
    }
    for(int i=0;i<pre[u].size();i++){
        int v=pre[u][i];
        temp.push_back(v);
        DFS(v);
        temp.pop_back();
    }
}
void Dijkstra(int s){
    fill(d,d+maxn,INF);
    fill(vis,vis+maxn,0);
    d[s]=0;
    for(int i=0;i<n;i++){
        int u=-1,_min=INF;
        for(int j=0;j<n;j++){
            if(!vis[j]&&d[j]<_min){
                _min=d[j];
                u=j;
            }
        }
        if(u==-1) return ;
        vis[u]=true;
        for(int j=0;j<G[u].size();j++){
            int v=G[u][j].v;
            int dis=G[u][j].dis;
            if(!vis[v]){
                if(d[u]+dis<d[v]){
                    d[v]=d[u]+dis;
                    pre[v].clear();
                    pre[v].push_back(u);
                }
                else if(d[u]+dis==d[v])
                    pre[v].push_back(u);
            }
        }
    }
}
int main()
{
    scanf("%d%d%s",&n,&k,_begin);
    char city[4];int happy;
    mp[_begin]=0;
    weight[0]=0;
    IntToString[0]=_begin;
    for(int i=1;i<=n-1;i++){
        scanf("%s%d",city,&happy);
        weight[i]=happy;
        mp[city]=i;
        IntToString[i]=city;
    }
    char city1[4],city2[4];int dis;
    for(int i=0;i<k;i++){
        scanf("%s%s%d",city1,city2,&dis);
        int a=mp[city1],b=mp[city2];
        G[a].push_back(Node(b,dis));
        G[b].push_back(Node(a,dis));
    }
    Dijkstra(0);
    int e=mp["ROM"];
    temp.push_back(e);
    DFS(e);
    printf("%d %d %d %d\n",cnt,d[e],sum_value,(int)a_value);
    for(int i=path.size()-1;i>=0;i--){
        printf("%s",IntToString[path[i]].c_str());
        if(i!=0)
            printf("->");
    }
    printf("\n");
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值