【PAT】1111 Online Map (30 分)

堆优化的dijkstra+第二标尺

两次权不同,互不干扰 

#include <bits/stdc++.h>
using namespace std;
int n,m;
int s1,s2;
#define maxn 520
int s[maxn][maxn];
int t[maxn][maxn];

int s_dist[maxn],s_path[maxn],s_tdist[maxn],collected[maxn];
struct cmp{
    bool operator () (pair<int, int> a, pair<int, int> b) {
        if (a.first != b.first) return a.first > b.first;
        else return s_tdist[a.second]>s_tdist[b.second];
    }
};
priority_queue<pair<int,int>,vector<pair<int,int> >,cmp > min_heap;

void s_dijkstra(){
    fill(s_dist,s_dist+n,INT_MAX);
    fill(s_tdist,s_tdist+n,INT_MAX);
    fill(collected,collected+n,0);
    s_dist[s1]=0,s_path[s1]=-1;
    min_heap.push(make_pair(0,s1));
    while(!min_heap.empty()){
        int minId=min_heap.top().second;
        int minS=min_heap.top().first;
        min_heap.pop();
        if(collected[minId]) continue;
        collected[minId]=1;
        for(int i=0;i<n;i++){
            if(collected[i]==0 && s[minId][i]!=INT_MAX){//未访问的邻接点
                if(s_dist[i]>minS+s[minId][i]){
                    s_dist[i] = minS + s[minId][i];
                    s_tdist[i] = s_tdist[minId]+t[minId][i];
                    s_path[i] = minId;
                    min_heap.push(make_pair(s_dist[i],i));
                }else if(s_dist[i]==minS+s[minId][i]){
                    if(s_tdist[i]>s_tdist[minId]+t[minId][i]){
                        s_tdist[i]=s_tdist[minId]+t[minId][i];
                        s_path[i] = minId;
                        min_heap.push(make_pair(s_dist[i],i));
                    }
                }
            }
        }
    }
}

int t_dist[maxn],t_num[maxn];
struct cmp1{
    bool operator () (pair<int, int> a, pair<int, int> b) {
        if (a.first != b.first) return a.first > b.first;
        else return t_num[a.second]>t_num[b.second];
    }
};
priority_queue<pair<int,int>,vector<pair<int,int> >,cmp1 > t_min_heap;
void t_dijkstra(){
    fill(t_dist,t_dist+n,INT_MAX);
    fill(t_num,t_num+n,0);
    fill(collected,collected+n,0);
    t_dist[s1]=0,t_num[s1]=1,s_path[s1]=-1;
    t_min_heap.push(make_pair(0,s1));
    while(!t_min_heap.empty()){
        int minId=t_min_heap.top().second;
        int minT=t_min_heap.top().first;
        t_min_heap.pop();
        if(collected[minId]) continue;
        collected[minId]=1;
        for(int i=0;i<n;i++){
            if(collected[i]==0 && t[minId][i]!=INT_MAX){//未访问的邻接点
                if(t_dist[i]>minT+t[minId][i]){
                    t_dist[i] = minT + t[minId][i];
                    s_path[i] = minId;
                    t_num[i]=t_num[minId]+1;
                    t_min_heap.push(make_pair(t_dist[i],i));
                }else if(t_dist[i]==minT+t[minId][i]){
                    if(t_num[i]>t_num[minId]+1){
                        s_path[i] = minId;
                        t_num[i] = t_num[minId] + 1;
                        t_min_heap.push(make_pair(t_dist[i], i));
                    }
                }
            }
        }
    }
}

vector<int> res_Spath;
void sPrintL(int root){
    if(root==-1) return;
    res_Spath.push_back(root);
    sPrintL(s_path[root]);
}

vector<int> res_Tpath;
void tPrintL(int root){
    if(root==-1) return;
    res_Tpath.push_back(root);
    tPrintL(s_path[root]);
}

void printRes1(){
    cout<<"Distance = "<<s_dist[s2]<<": "<<res_Spath[(int)res_Spath.size()-1];
    for(int i=(int)res_Spath.size()-2;i>=0;i--)
        cout<<" -> "<<res_Spath[i];
    cout<<"\nTime = "<<t_dist[s2]<<": "<<res_Tpath[(int)res_Tpath.size()-1];
    for(int i=(int)res_Tpath.size()-2;i>=0;i--)
        cout<<" -> "<<res_Tpath[i];
}

void printRes2(){
    cout<<"Distance = "<<s_dist[s2]<<"; Time = "<<t_dist[s2]<<": "<<res_Tpath[(int)res_Tpath.size()-1];
    for(int i=(int)res_Tpath.size()-2;i>=0;i--)
        cout<<" -> "<<res_Tpath[i];
}

int main(){
    cin>>n>>m;
    int v1,v2,v_one_way,v_length,v_time;
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++) s[i][j]=INT_MAX,t[i][j]=INT_MAX;
    }
    for(int i=0;i<m;i++){
        cin>>v1>>v2>>v_one_way>>v_length>>v_time;
        if(v_one_way==0){
            s[v1][v2]=v_length,s[v2][v1]=v_length;
            t[v1][v2]=v_time,t[v2][v1]=v_time;
        }else{
            s[v1][v2]=v_length;
            t[v1][v2]=v_time;
        }
    }
    cin>>s1>>s2;
    s_dijkstra();
    sPrintL(s2);
    t_dijkstra();
    tPrintL(s2);
    int flag=1;
    for(int i=0;i<n;i++){
        if(res_Spath[i]!=res_Tpath[i]) flag=0;
    }
    if(flag==0) printRes1();
    else        printRes2();

    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值