【PAT】1087 All Roads Lead to Rome (30 分)

三个标尺:

1.cost最小【边权】

2. happiness最大【点权】

3.average_happiness最大【经过结点数最少】

但因为还需要根据cost最小,输出路径条数,所以重新dijkstra一下

#include <bits/stdc++.h>
using namespace std;
#define maxn 210
int n,k;
string s1;
struct citys{
  string name;
  int happiness;
};
int cost[maxn][maxn];//cost[i][j]=i->j_cost
vector<citys> city;  //city[city_id] .name .happiness
unordered_map<string,int> mp;//mp[city_name]=city_id

int dist[maxn],h[maxn],cnt[maxn];
int visited[maxn],path[maxn];
struct cmp{
    bool operator () (citys &a,citys &b){
        if(dist[mp[a.name]]!=dist[mp[b.name]])
            return dist[mp[a.name]]>dist[mp[b.name]];
        else
            if(h[mp[a.name]]!=h[mp[b.name]])
                return h[mp[a.name]]<h[mp[b.name]];
            else
                return cnt[mp[a.name]]>cnt[mp[b.name]];
    }
};
priority_queue<citys,vector<citys>,cmp> heap;
void dijkstra(){
    fill(dist,dist+maxn,INT_MAX);
    fill(cnt,cnt+maxn, INT_MAX);
    dist[mp[s1]]=0,h[mp[s1]]=0,cnt[mp[s1]]=0,path[mp[s1]]=-1;
    heap.push(citys{s1,city[mp[s1]].happiness});
    while(!heap.empty()){
        citys temp=heap.top();
        heap.pop();
        if(visited[mp[temp.name]]) continue;
        visited[mp[temp.name]]=1;
        for(int i=0;i<n;i++){
            if(visited[i]==0 && cost[mp[temp.name]][i]!=INT_MAX){
                if(dist[i]>dist[mp[temp.name]]+cost[mp[temp.name]][i]){
                    dist[i]=dist[mp[temp.name]]+cost[mp[temp.name]][i];
                    h[i]=h[mp[temp.name]]+city[i].happiness;
                    cnt[i]=cnt[mp[temp.name]]+1;
                    path[i]=mp[temp.name];
                    heap.push(citys{city[i].name,city[i].happiness});
                }else if(dist[i]==dist[mp[temp.name]]+cost[mp[temp.name]][i]){
                    if(h[i]<h[mp[temp.name]]+city[i].happiness){
                        h[i]=h[mp[temp.name]]+city[i].happiness;
                        cnt[i]=cnt[mp[temp.name]]+1;
                        path[i]=mp[temp.name];
                        heap.push(citys{city[i].name,city[i].happiness});
                    }else if(h[i]==h[mp[temp.name]]+city[i].happiness && cnt[i]>cnt[mp[temp.name]]+1){
                        cnt[i]=cnt[mp[temp.name]]+1;
                        path[i]=mp[temp.name];
                        heap.push(citys{city[i].name,city[i].happiness});
                    }
                }
            }
        }
    }
}
vector<int> resPath;
void printPath(int root){
    if(root==-1) return;
    resPath.push_back(root);
    printPath(path[root]);
}

int dist_s[maxn],visited_s[maxn],cnt_s[maxn];
struct cmp1{
    bool operator () (citys &a, citys &b){
        return dist_s[mp[a.name]]>dist_s[mp[b.name]];
    }
};
priority_queue<citys,vector<citys>,cmp1> heap_s;
void dijkstra_s(){
    fill(dist_s,dist_s+maxn,INT_MAX);
    dist_s[mp[s1]]=0,cnt_s[mp[s1]]=1;
    heap_s.push(citys{s1,city[mp[s1]].happiness});
    while(!heap_s.empty()){
        citys temp = heap_s.top();
        heap_s.pop();
        if(visited_s[mp[temp.name]]) continue;
        visited_s[mp[temp.name]]=1;
        for(int i=0;i<n;i++){
            if(visited_s[i]==0 && cost[mp[temp.name]][i]!=INT_MAX){
                if(dist_s[i]>dist_s[mp[temp.name]]+cost[mp[temp.name]][i]){
                    dist_s[i]=dist_s[mp[temp.name]]+cost[mp[temp.name]][i];
                    cnt_s[i]=cnt_s[mp[temp.name]];
                    heap_s.push(citys{city[i].name,city[i].happiness});
                }else if(dist_s[i]==dist_s[mp[temp.name]]+cost[mp[temp.name]][i]){
                    cnt_s[i]+=cnt_s[mp[temp.name]];
                    heap_s.push(citys{city[i].name,city[i].happiness});
                }
            }
        }
    }
}
int main(){
    cin>>n>>k>>s1;
    city.resize(n);
    city[0].name=s1,city[0].happiness=0,mp[s1]=0;
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            cost[i][j]=INT_MAX;
        }
    }
    string tc;
    int th;
    for(int i=1;i<n;i++){
        cin>>tc>>th;
        mp[tc]=i,city[i].name=tc,city[i].happiness=th;
    }

    string c1,c2;
    int cc;
    for(int i=0;i<k;i++){
        cin>>c1>>c2>>cc;
        cost[mp[c1]][mp[c2]]=cc;
        cost[mp[c2]][mp[c1]]=cc;
    }

    dijkstra();
    dijkstra_s();
    cout<<cnt_s[mp["ROM"]]<<" ";
    cout<<dist[mp["ROM"]]<<" ";
    cout<<h[mp["ROM"]]<<" ";
    cout<<h[mp["ROM"]]/cnt[mp["ROM"]]<<endl;

    printPath(mp["ROM"]);
    for(int i=resPath.size()-1;i>=0;i--){
        if(i!=0) cout<<city[resPath[i]].name<<"->";
        else     cout<<city[resPath[i]].name;
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值