PAT.A1030トラベルプラン

目次に戻るここに画像の説明を挿入

タイトル

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

注意点

  1. この質問では、ダイクストラを使用します。
  2. 初期値でフィルを使用すると、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;
}
元の記事を177件公開しました 賞賛されました5 訪問6651

おすすめ

転載: blog.csdn.net/a1920993165/article/details/105576199