1. 程式人生 > 其它 >PAT A1030 Travel Plan (30 分)

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;
    
}