PAT A1030 Travel Plan (30 分)
阿新 • • 發佈:2022-01-10
直接採用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;
}