PAT A1030 Travel Plan (30 分)

直接采用Dijkstra算法

#include<iostream>
#include<vector>
#include<cstdio>
using namespace std;
const int INF=1000000;
int dis[500][500],mindis[500],cost[500][500],mincost[500],pre[500];//从左至右依次表示【两个城市之间的距离】,【两个城市之间的最短距离】,【两个城市之间的花费】,【两个城市之间的最少花费】,【符合要求的直接前驱】
bool vis[500]={false};
vector<int> v[500];
int N,M,S,D;
void Dijkstra(int S){
    fill(mindis,mindis+500,INF);
    fill(mincost,mincost+500,INF);
    mindis[S]=0;
    mincost[S]=0;
    for(int i=0;i<N;i++){
        int u=-1,MIN=INF;
        for(int j=0;j<N;j++){
            if(vis[j]==false&&mindis[j]<MIN){
                MIN=mindis[j];
                u=j;
            }
        }
        if(u==-1)return;
        vis[u]=true;
        for(int i=0;i<v[u].size();i++){
            int j=v[u][i];
            if(vis[j]==false){
                if(mindis[u]+dis[u][j]<mindis[j]){
                    mindis[j]=mindis[u]+dis[u][j];
                    mincost[j]=mincost[u]+cost[u][j];
                    pre[j]=u;
                }
                else if(mindis[u]+dis[u][j]==mindis[j]){                    
                    if(mincost[u]+cost[u][j]<mincost[j]){
                        mincost[j]=mincost[u]+cost[u][j];
                        pre[j]=u;
                    }                    
                }
            }
        }
    }
}
void DFS(int v){
    if(v==S){
        printf("%d ",v);
        return;
    }DFS(pre[v]);
    printf("%d ",v);
}
int main(){
    int i,j,k,l,c;
    cin>>N>>M>>S>>D;
    for(i=0;i<M;i++){
        cin>>j>>k>>l>>c;
        v[k].push_back(j);
        v[j].push_back(k);
        dis[j][k]=dis[k][j]=l;
        cost[j][k]=cost[k][j]=c;
    }
    Dijkstra(S);
    DFS(D);
    printf("%d %d",mindis[D],mincost[D]);
    return 0;
}

采用Dijkstra算法求出最短路径后,再通过DFS对第二标尺进行二次判定

#include<iostream>
#include<vector>
#include<cstdio>
using namespace std;
const int INF=1000000;
int dis[500][500],mindis[500],cost[500][500];
int mincost=INF;//最少花费 
bool vis[500]={false};
vector<int> v[500];
vector<int> pre[500];
vector<int> temppath,path;//临时路径,最优路径 

int N,M,S,D;
void Dijkstra(int S){
    fill(mindis,mindis+500,INF);    
    mindis[S]=0; 
    for(int i=0;i<N;i++){
        int u=-1,MIN=INF;
        for(int j=0;j<N;j++){
            if(vis[j]==false&&mindis[j]<MIN){
                MIN=mindis[j];
                u=j;
            }
        }
        if(u==-1)return;
        vis[u]=true;
        for(int i=0;i<v[u].size();i++){
            int j=v[u][i];
            if(vis[j]==false){
                if(mindis[u]+dis[u][j]<mindis[j]){
                    mindis[j]=mindis[u]+dis[u][j];
                    pre[j].clear();
                    pre[j].push_back(u);
                }
                else if(mindis[u]+dis[u][j]==mindis[j]){                    
                    pre[j].push_back(u);        
                }
            }
        }
    }
}
void DFS(int v){
    temppath.push_back(v);
    if(v==S){        
        int tempcost=0;
        for(int i=temppath.size()-1;i>0;i--){
            int id=temppath[i],idNext=temppath[i-1];
            tempcost+=cost[id][idNext];
        }
        if(tempcost<mincost){
            mincost=tempcost;
            path=temppath;
        }
        temppath.pop_back();
        return;
    }
    
    for(int i=0;i<pre[v].size();i++){
        DFS(pre[v][i]);
    }
    
    temppath.pop_back();
}
int main(){
    int i,j,k,l,c;
    cin>>N>>M>>S>>D;
    for(i=0;i<M;i++){
        cin>>j>>k>>l>>c;
        v[k].push_back(j);
        v[j].push_back(k);
        dis[j][k]=dis[k][j]=l;
        cost[j][k]=cost[k][j]=c;
    }
    Dijkstra(S);
    DFS(D);
    for(int i=path.size()-1;i>=0;i--){
        printf("%d ",path[i]);
    }
    printf("%d %d",mindis[D],mincost);
    return 0;
}

或者从题目出发,直接采用DFS进行递归求解

 

#include<iostream>
#include<vector>
#include<cstdio>
using namespace std;
const int INF=1000000;
int dis[500][500],mindis[500],cost[500][500],mincost[500];
int mincosttoD=INF;//到达D的最少路径
int mindistoD=INF;//到达D的最短路径
int N,M,S,D;
vector<int>v[500];
vector<int> temppath,path;//临时路径,最优路径 
void DFS(int curcity,int curlen,int curcost){
    if(curlen>mindis[curcity]) return;
    temppath.push_back(curcity);
    if(curcity==D){
        if(curlen<mindis[D]||(curlen==mindis[D]&&curcost<mincost[D])){
            mindistoD=mindis[D]=curlen;
            mincosttoD=mincost[D]=curcost;
            path=temppath;
        }
    }
    else{
        if(curlen<mindis[curcity]){//直接对第一标尺进行判断
            mindis[curcity]=curlen;
        }
        for(int o: v[curcity]){
            DFS(o,curlen+dis[o][curcity],curcost+cost[o][curcity]);
        }
    }
    temppath.pop_back();
}
int main(){
    int i,j,k,l,c;
    cin>>N>>M>>S>>D;
    for(i=0;i<M;i++){
        cin>>j>>k>>l>>c;
        v[k].push_back(j);
        v[j].push_back(k);
        dis[j][k]=dis[k][j]=l;
        cost[j][k]=cost[k][j]=c;
    }
fill(mindis,mindis+500,INF);
fill(mincost,mincost+500,INF);
DFS(S,0,0);
for(int i=0;i<path.size();i++){
    printf("%d ",path[i]);
}
cout<<mindistoD<<" "<<mincosttoD;
    
}

 

上一篇:第2章-8 转换函数使用 (30 分)


下一篇:20190324游戏场景百度地图150次联网耗电