返回目录![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/e66cd87677abb12d6425735175dfd11e.png)
题意
有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
注意点
- 本题使用Dijkstra。
- 注意使用fill附初值,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;
}