迪杰斯特拉算法应用(+DFS)——PAT A1030 Travel Plan

《算法笔记》P385
emmm迪杰斯特拉算法来求图的最短路径,书上的模板套一套就可以了嘛?

方法一:纯Dijkstra代码:

#include <stdio.h>
#include <cstring>
#include <algorithm>
using namespace std;

const int maxn = 510;
const int INF = 1000000000;
//n为顶点数,m为边数,st和ed分别为起点和终点
//G为距离矩阵,c[]记录最小花费,d[]记录最短距离
int n,m,st,ed,G[maxn][maxn],cost[maxn][maxn];
int d[maxn],c[maxn],pre[maxn];
bool vis[maxn] = {false};

void Dijkstra(int s){
	fill(d,d+maxn,INF);
	fill(c,c+maxn,INF);
	for(int i = 0;i <n;i++){
		pre[i] = i;   //每个前驱设为自身 
	}
	d[s] = 0;
	c[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 && d[j] <MIN){
				u = j;
				MIN = d[j];
			}
		}
		if(u == -1) return;
		vis[u] = true;
		for(int v = 0;v <n;v++){
			if(vis[v] == false && G[u][v] != INF){
				if(d[u] + G[u][v] <d[v]){
					d[v] = d[u] + G[u][v];
					c[v] = c[u] + cost[u][v];
					pre[v] = u;
				}
				else if(d[u] + G[u][v] == d[v]){
					if(c[u] + cost[u][v] <c[v]){
						c[v] = c[u] + cost[u][v];
						pre[v] = u;
					}
				}
			}
		}
	}
}

void DFS(int v){
	if(v == st){
		printf("%d ",v);
		return;
	}
	DFS(pre[v]);
	printf("%d ",v);
}

int main(){
	scanf("%d%d%d%d",&n,&m,&st,&ed);
	int u,v;
	fill(G[0],G[0] + maxn*maxn,INF);
	for(int i = 0;i <m;i++){
		scanf("%d%d",&u,&v);
		scanf("%d%d",&G[u][v],&cost[u][v]);
		G[v][u] = G[u][v];
		cost[v][u] = cost[u][v];
	}
	Dijkstra(st);
	DFS(ed);
	printf("%d %d\n",d[ed],c[ed]);   //最短距离、最短路径下的最小花费 
	return 0;
} 

/*
4 5 0 3
0 1 1 20
1 3 2 30
0 3 4 10
0 2 2 20
2 3 1 20

*/

方法二:Dijkstra + DFS(需处理)
其实感觉这两种方法,纯用迪杰斯特拉似乎比较好操作?

#include <stdio.h>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;

const int maxn = 510;
const int INF = 1000000000;

int n,m,st,ed,G[maxn][maxn],cost[maxn][maxn];
int d[maxn],mincost = INF;   //mincost记录最短路径上的最小花费 
bool vis[maxn] = {false};
vector<int> pre[maxn];
vector<int> tempth,path;

void Dijkstra(int s){
	fill(d,d+maxn,INF);
	d[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 && d[j] <MIN){
				u = j;
				MIN = d[j];
			}
		}
		if(u == -1) return;
		vis[u] = true;
		for(int v = 0;v <n;v++){
			if(vis[v] == false && G[u][v] != INF){
				if(d[u] + G[u][v] <d[v]){
					d[v] = d[u] + G[u][v];
					pre[v].clear();
					pre[v].push_back(u);
				}
				else if(d[u] + G[u][v] == d[v]){
					pre[v].push_back(u);
				}
			}
		}
	}
} 

void DFS(int v){
	if(v == st){
		tempth.push_back(v);
		int tempcost = 0;
		for(int i = tempth.size() - 1;i > 0;i--){
			int id = tempth[i],idnext = tempth[i-1];
			tempcost += cost[id][idnext];
		}
		if(tempcost <mincost){
			mincost = tempcost;
			path = tempth;
		}
		tempth.pop_back();
		return;
	}
	tempth.push_back(v);
	for(int i = 0;i <pre[v].size();i++){
		DFS(pre[v][i]);
	}
	tempth.pop_back();
}

int main(){
	scanf("%d%d%d%d",&n,&m,&st,&ed);
	int u,v;
	fill(G[0],G[0] + maxn*maxn,INF);
	fill(cost[0],cost[0] + maxn*maxn,INF);
	for(int i = 0;i <m;i++){
		scanf("%d%d",&u,&v);
		scanf("%d%d",&G[u][v],&cost[u][v]);
		G[v][u] = G[u][v];
		cost[v][u] = cost[u][v];
	}
	Dijkstra(st);
	DFS(ed);
	for(int i = path.size() - 1;i >= 0;i--){
		printf("%d ",path[i]);
	}
	printf("%d %d\n",d[ed],mincost);
	return 0;
}
发布了212 篇原创文章 · 获赞 6 · 访问量 6396

猜你喜欢

转载自blog.csdn.net/weixin_42377217/article/details/104303547
今日推荐