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

题目链接

题目类型:带路径的单源最短路径

出现的错误:忘记初始化roadCost为inf,导致pre没有元素,后续getRoad函数访问pre[end][0]出现段错误

#include<bits/stdc++.h>
#define MAXN 210
using namespace std;
const int inf=1000000;
map<int,string> index_name;
map<string,int> name_index;
int happy[MAXN];
int cost[MAXN][MAXN];//成本
bool vis[MAXN];
int roadCost[MAXN],roadNum[MAXN],w[MAXN];
vector<int> pre[MAXN];
stack<int> ans;
int n,k;
string start_name;

void dijkstra(int start){
    roadCost[start]=0;
    roadNum[start]=1;

    for(int i=0;i<n;i++){
        int u=-1,minCost=inf;
        for(int j=0;j<n;j++){
            if(!vis[j]&&roadCost[j]<minCost){
                u=j,minCost=roadCost[j];
            }
        }
        if(u!=-1){
            vis[u]=true;
        }
        else{
            return;
        }
//        cout<<"u:"<<u<<endl;
        //更新
        for(int v=0;v<n;v++){
            if(!vis[v]&& (roadCost[v]>roadCost[u]+cost[u][v]) ){
                roadCost[v]=roadCost[u]+cost[u][v];
                pre[v].clear();pre[v].push_back(u);
                roadNum[v]=roadNum[u];
                w[v]=w[u]+happy[v];
//                cout<<"pre:"<<pre[v][0]<<endl;
            }
            else if(!vis[v]&& (roadCost[v]==roadCost[u]+cost[u][v]) ){
                roadNum[v] += roadNum[u];
                if(w[v]<w[u]+happy[v]){
                    pre[v].clear();pre[v].push_back(u);
                    w[v]=w[u]+happy[v];
                }
                else if(w[v]==w[u]+happy[v]){
                    pre[v].push_back(u);
                }
//                cout<<"pre:"<<pre[v][0]<<endl;
            }
            
        }
    }
}

int getRoad(int start,int end,int sum){
    if(start==end){
        return sum;
    }
    ans.push(end);
    return getRoad(start,pre[end][0],sum+1);
}

int main(){
    memset(cost,inf,sizeof(cost));
    memset(roadCost,inf,sizeof(roadCost));
    memset(vis,false,sizeof(vis));
    cin>>n>>k>>start_name;
    index_name[0]=start_name;
    name_index[start_name]=0;
    
    for(int i=1;i<n;i++){
        string s;
        int h;
        cin>>s>>h;
        index_name[i]=s;
        name_index[s]=i;
        happy[i]=h;
    }
    for(int i=0;i<k;i++){
        string a,b;int c;
        cin>>a>>b>>c;
        int a_i=name_index[a];
        int b_i=name_index[b];
        cost[a_i][b_i]=cost[b_i][a_i]=c;
//        cout<<"test:"<<cost[a_i][b_i]<<endl;
    }
    dijkstra(0);

    int sum=getRoad(0,name_index["ROM"],0);
    int ave=w[name_index["ROM"]]/sum;
    cout<<roadNum[name_index["ROM"]]<<" "<<roadCost[name_index["ROM"]]<<" "<<w[name_index["ROM"]]<<" "<<ave<<endl;
    cout<<start_name;
    while(!ans.empty()){
        string s=index_name[ans.top()];
        ans.pop();
        cout<<"->"<<s;
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值