1111 Online Map

这篇博客介绍了1111 Online Map问题的解决方案,主要探讨了使用优先队列(重载运算符)优化的Dijkstra算法以及普通Dijkstra结合DFS遍历pre的方法。详细阐述了路线规划的精妙之处。
摘要由CSDN通过智能技术生成

1111 Online Map (30 分)

题目地址

优先队列(重载运算符)优化的dijkstra,route很精妙

#include <stdio.h>
#include <iostream>
#include <vector>
#include <queue>
#define INF 0x3fffffff
#define MAX 502
using namespace std;

int n,m;
vector<int> edge[MAX];
int distmap[MAX][MAX];
int timemap[MAX][MAX];

//res:
int mindist,mintime;
vector<int> resDistRoute,resTimeRoute;

struct Vertex{
    int x,dist;
    bool operator <(const Vertex &v) const{
        return dist>v.dist;
    }
};
void buildEdge(int st,int ed,int length,int time){
    edge[st].push_back(ed);
    distmap[st][ed]=length;
    timemap[st][ed]=time;
}

void dijkstra1(int st,int ed){
    vector<bool> vis(n,false);
    vector<int> dist(n,INF),time(n,INF);
    vector<vector<int> > route(n);
    priority_queue<Vertex> pq;
    dist[st]=time[st]=0;
    pq.push(Vertex{st,0});
    while(!pq.empty()){
        int f=pq.top().x;
        pq.pop();

        if(vis[f]) continue;
        vis[f]=true;
        route[f].push_back(f);
        if(f==ed) break;
        for(int i=0;i<edge[f].size();i++){
            int to=edge[f][i];
            if(vis[to]) continue;
            if(dist[to]>dist[f]+distmap[f][to]||
            (dist[to]==dist[f]+distmap[f][to]&&time[to]>time[f]+timemap[f][to])){
                dist[to]=dist[f]+distmap[f][to];
                time[to]=time[f]+timemap[f][to];
                route[to]=route[f];
                pq.push(Vertex{to,dist[to]});
            }
        }
    }
    resDistRoute=route[ed];
    mindist=dist[ed];
}

void dijkstra2(int st,int ed){
    vector<bool> vis(n,false);
    vector<int> time(n,INF);
    vector<vector<int> > route(n);
    priority_queue<Vertex> pq;
    time[st]=0;
    pq.push(Vertex{st,0});
    while(!pq.empty()){
        int f=pq.top().x;
        pq.pop();
        if(vis[f]) continue;
        vis[f]=true;
        route[f].push_back(f);
        if(f==ed) break;
        for(int i=0;i<edge[f].size();i++){
            int to=edge[f][i];
            if(vis[to]) continue;
            if(time[to]>time[f]+timemap[f][to]||
               (time[to]==time[f]+timemap[f][to]&&route[to].size()>route[f].size())
               ){
                time[to]=time[f]+timemap[f][to];
                route[to]=route[f];
                pq.push(Vertex{to,time[to]});
               }
        }
    }
    mintime=time[ed];
    resTimeRoute=route[ed];
}
void ppath(vector<int> path){
    for(int i=0;i<path.size();i++)
        printf(" %d%s",path[i],i==path.size()-1?"\n":" ->");
}
int main(){
//    freopen("1.txt","r",stdin);

    scanf("%d%d",&n,&m);
    for(int i=0;i<m;i++){
        int v1,v2,o,l,t;
        scanf("%d%d%d%d%d",&v1,&v2,&o,&l,&t);
        buildEdge(v1,v2,l,t);
        if(o==0) buildEdge(v2,v1,l,t);
    }
    int s,e;
    scanf("%d%d",&s,&e);
    dijkstra1(s,e);
    dijkstra2(s,e);
    if(resDistRoute==resTimeRoute){
        printf("Distance = %d; Time = %d:",mindist,mintime);
        ppath(resDistRoute);
    }else{
        printf("Distance = %d:",mindist);
        ppath(resDistRoute);
        printf("Time = %d:",mintime);
        ppath(resTimeRoute);
    }
    return 0;
}


普通dijkstra+dfs遍历pre

#include <stdio.h>
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#define INF 0x3fffffff
using namespace std;

int n,m,a,b,oneway,templen,temptime;
int tm[520][520],dist[520][520];
int d[520],t[520];
bool vis[520];
vector<int> timepre[520],distpre[520];
vector<int> tempv,distres,timeres;
int mintime2dist=INF,mindist2time=INF;

void dfs1(int s,int e){
    if(s==e){
        int sum=0;
        tempv.push_back(s);
        for(int i=tempv.size()-1;i>0;i--){
            sum+=tm[tempv[i]][tempv[i-1]];
        }
        if(sum<mintime2dist){
            distres=tempv;
            mintime2dist=sum;
        }
        tempv.pop_back();
        return;
    }

    for(int i=0;i<distpre[s].size();i++){
        tempv.push_back(s);
        dfs1(distpre[s][i],e);
        tempv.pop_back();
    }
}
void dfs2(int s,int e){
    if(s==e){
        int sum=0;
        tempv.push_back(s);
        if(tempv.size()<mindist2time){
            timeres=tempv;
            mindist2time=tempv.size();
        }
        tempv.pop_back();
        return;
    }

    for(int i=0;i<timepre[s].size();i++){
        tempv.push_back(s);
        dfs2(timepre[s][i],e);
        tempv.pop_back();
    }
}
void dijkstra1(int s){//shortest
    fill(d,d+520,INF);
    fill(vis,vis+520,false);
    d[s]=0;

    for(int i=0;i<n;i++){
        int u=-1,MIN=INF;
        for(int j=0;j<n;j++){
            if(d[j]<MIN&&vis[j]==false){
                MIN=d[j];u=j;
            }
        }
        vis[u]=true;
        if(u==-1) return;

        for(int j=0;j<n;j++){
            if(vis[j]==false&&dist[u][j]<INF){
                if(d[j]>d[u]+dist[u][j]){
                    d[j]=d[u]+dist[u][j];
                    distpre[j].clear();
                    distpre[j].push_back(u);
                }else if(d[j]==d[u]+dist[u][j]){
                    distpre[j].push_back(u);
                }
            }
        }
    }
}
void dijkstra2(int s){//fastest
    fill(t,t+520,INF);
    fill(vis,vis+520,false);
    t[s]=0;

    for(int i=0;i<n;i++){
        int u=-1,MIN=INF;
        for(int j=0;j<n;j++){
            if(t[j]<MIN&&vis[j]==false){
                MIN=t[j];u=j;
            }
        }
        vis[u]=true;
        if(u==-1) return;

        for(int j=0;j<n;j++){
            if(vis[j]==false&&tm[u][j]<INF){
                if(t[j]>t[u]+tm[u][j]){
                    t[j]=t[u]+tm[u][j];
                    timepre[j].clear();
                    timepre[j].push_back(u);
                }else if(t[j]==t[u]+tm[u][j]){
                    timepre[j].push_back(u);
                }
            }
        }
    }
}

int main(){
//    freopen("1.txt","r",stdin);
    scanf("%d%d",&n,&m);
    fill(tm[0],tm[0]+520*520,INF);
    fill(dist[0],dist[0]+520*520,INF);
    for(int i=0;i<m;i++){
        scanf("%d%d%d%d%d",&a,&b,&oneway,&templen,&temptime);
        if(oneway==0){
            tm[b][a]=min(tm[b][a],temptime);
            dist[b][a]=min(dist[b][a],templen);
        }
        tm[a][b]=min(tm[a][b],temptime);
        dist[a][b]=min(dist[a][b],templen);
    }
    int s,e;
    scanf("%d%d",&s,&e);
    dijkstra1(s);//shortest
    dfs1(e,s);
    tempv.clear();
    dijkstra2(s);//fastest
    dfs2(e,s);
    reverse(distres.begin(),distres.end());
    reverse(timeres.begin(),timeres.end());
    int restime=0,resdist=0;
    for(int i=0;i<distres.size()-1;i++){
        resdist+=dist[distres[i]][distres[i+1]];
    }
    for(int i=0;i<timeres.size()-1;i++){
        restime+=tm[timeres[i]][timeres[i+1]];
    }
    if(timeres==distres){
        printf("Distance = %d; Time = %d:",resdist,restime);
        for(int i=0;i<distres.size();i++){
            printf(" %d",distres[i]);
            if(i!=distres.size()-1) printf(" ->");
        }
    }else{
        printf("Distance = %d:",resdist);
        for(int i=0;i<distres.size();i++){
            printf(" %d",distres[i]);
            if(i!=distres.size()-1) printf(" ->");
        }
        printf("\nTime = %d:",restime);
        for(int i=0;i<timeres.size();i++){
            printf(" %d",timeres[i]);
            if(i!=timeres.size()-1) printf(" ->");
        }
    }
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值