目次に戻る
タイトル
N個の都市(0〜N-1の番号が付けられている)、M個の道路(無向エッジ)、およびM個の道路の距離属性とコスト属性が示されています。ここで、開始点Sと終了点Dが与えられたときに、開始点から終了点までの最短経路、最短距離、およびコストを求めます。注:複数の最短経路がある場合は、コストが最小の経路を選択してください。
サンプル(コピー可能)
4 5 0 3
0 1 1 20
1 3 2 30
0 3 4 10
0 2 2 20
2 3 1 20
//output
0 2 3 3 40
注意点
- この質問では、ダイクストラを使用します。
- 初期値でフィルを使用すると、memsetは0、-1、falseを割り当てるためにのみ使用されることに注意してください。
#include <bits/stdc++.h>
using namespace std;
int n,m,st,ed;//城市,边,起点,终点
int D[510][510],F[510][510];//D存放距离,F存放费用
int dis[510];//存放从st出发的距离
bool vis[510]={false};//标记是否访问过
int pre[510],fee[510];//最优前驱,费用
vector<int> path;//存放最优路径
void Dijkstra(){
fill(dis,dis+n,INT_MAX);
fill(fee,fee+n,INT_MAX);
dis[st]=0;
fee[st]=0;
while(!vis[ed]){
int minn=INT_MAX,v;
for(int i=0;i<n;i++){
if(!vis[i]&&dis[i]<minn){
minn=dis[i];
v=i;
}
}
vis[v]=true;
for(int i=0;i<n;i++){
if(!vis[i]&&D[v][i]!=0&&dis[i]>dis[v]+D[v][i]){
pre[i]=v;
fee[i]=fee[v]+F[v][i];
dis[i]=dis[v]+D[v][i];
}else if(D[v][i]!=0&&dis[i]==dis[v]+D[v][i]&&fee[i]>fee[v]+F[v][i]){
pre[i]=v;
fee[i]=fee[v]+F[v][i];
}
}
}
}
void DFS(int v){
path.push_back(v);
if(v==st)return;
DFS(pre[v]);
}
int main(){
cin>>n>>m>>st>>ed;
int u,v,d,f;
while(m--){
scanf("%d%d%d%d",&u,&v,&d,&f);
D[u][v]=D[v][u]=d;
F[u][v]=F[v][u]=f;
}
Dijkstra();
DFS(ed);
for(int i=path.size()-1;i>=0;i--)printf("%d ",path[i]);
printf("%d %d",dis[ed],fee[ed]);
return 0;
}