PAT 1111 Online Map

dijstra经典题

相同路径取用时最短

相同用时取节点数最少

但注意用vector存储节点时,每次更新需要清空之前的值,保存最新的路径。

参考自:https://www.liuchuo.net/archives/2407

#include <iostream>
#include<cstdio>
#include<vector>
#define MAX 99999999
using namespace std;
int n,m,s,t;
int dis[505],cosd[505],vis[505],cost[505],num[505];
struct Edge{
    int next;
    int dis;
    int time;
};
vector<Edge> ed[505];
vector<int> ansd,anst,path;
vector<int> pred[505],pret[505];//最短路前缀数组 
void dfsd(int v){
    ansd.push_back(v);
    if(v==s) return;
    dfsd(pred[v][0]);
}

void dfst(int v){
    anst.push_back(v);
    if(v==s) return;
    dfst(pret[v][0]);
}
void print(vector<int> v){
    for(int i=v.size()-1;i>=0;i--){
        if(i==v.size()-1) printf("%d",v[i]);
        else printf(" -> %d",v[i]);
    }
    printf("\n");
}
int main(int argc, char** argv) {
    scanf("%d%d",&n,&m);
    for(int i=0;i<m;i++){
        int v1,v2,tag,length,time;
        scanf("%d %d %d %d %d",&v1,&v2,&tag,&length,&time);
        Edge tmp;
        tmp.next=v2;tmp.dis=length;tmp.time=time;
        ed[v1].push_back(tmp);
        if(!tag){
            Edge tmp;
            tmp.next=v1;tmp.dis=length;tmp.time=time;
            ed[v2].push_back(tmp);
        }  //0为双向 
            
    }
    scanf("%d%d",&s,&t);
    
    for(int i=0;i<n;i++){
        dis[i]=MAX;
        vis[i]=0;
        cosd[i]=MAX;
        
        cost[i]=MAX;
        num[i]=MAX;
    }
    dis[s]=0,cosd[s]=0;
    num[s]=0,cost[s]=0;
    
    
    for(int i=0;i<n;i++){
        int minv=MAX,ind=-1;
        for(int j=0;j<n;j++){
            if(!vis[j]){
                if(dis[j]<minv){
                    minv=dis[j];
                    ind=j;
                }
            }
        }
        
        vis[ind]=1;
        for(int j=0;j<ed[ind].size();j++){
            int tmp=ed[ind][j].next;
            if(!vis[tmp]){
                if(dis[tmp]>dis[ind]+ed[ind][j].dis){
                    dis[tmp]=dis[ind]+ed[ind][j].dis;
                    cosd[tmp]=cosd[ind]+ed[ind][j].time;
                    pred[tmp].clear();
                    pred[tmp].push_back(ind);//前缀数组 
                }else if(dis[tmp]==dis[ind]+ed[ind][j].dis&&cosd[tmp]>cosd[ind]+ed[ind][j].time){
                      cosd[tmp]=cosd[ind]+ed[ind][j].time;//
                      pred[tmp].clear();
                    pred[tmp].push_back(ind);
                }
            }
        }
    }
    dfsd(t);
    
    //时间最短
    fill(vis,vis+505,0); 
    for(int i=0;i<n;i++){
        int minv=MAX,ind=-1;
        for(int j=0;j<n;j++){
            if(!vis[j]){
                if(cost[j]<minv){
                    minv=cost[j];
                    ind=j;
                }
            }
        }
        
        vis[ind]=1;
        for(int j=0;j<ed[ind].size();j++){
            int tmp=ed[ind][j].next;
            if(!vis[tmp]){
                if(cost[tmp]>cost[ind]+ed[ind][j].time){
                    cost[tmp]=cost[ind]+ed[ind][j].time;
                    num[tmp]=num[ind]+1;//
                    pret[tmp].clear();
                    pret[tmp].push_back(ind);//前缀数组 
                }else if(cost[tmp]==cost[ind]+ed[ind][j].time&&num[tmp]>num[ind]+1){
                      num[tmp]=num[ind]+1;
                      pret[tmp].clear();
                    pret[tmp].push_back(ind);//每次弹出之前的值,更新 
                }
            }
        }
    }
    dfst(t);
    if(ansd==anst){
        printf("Distance = %d; Time = %d: ",dis[t],cost[t]);
        print(anst);
    }else{
        printf("Distance = %d: ",dis[t]);
        print(ansd);
        printf("Time = %d: ",cost[t]);
        print(anst);
    }
    
    return 0;
}

 

posted @ 2018-11-16 09:44  xzhws  阅读(293)  评论(0编辑  收藏  举报