A1030 Travel Plan [dj]

在这里插入图片描述

dj算法:
直接找最短路径

#include<iostream>
#include<vector>
#include<queue>
#include<stack>
#include<string>
#include<math.h>
#include<algorithm>
#include<map>
#include<cstring>
#include<set>
using namespace std;
const int maxn = 501;
const int inf = 1000000000;
int d[maxn], c[maxn], pre[maxn];
int G[maxn][maxn], C[maxn][maxn];
int n, m, st, ed;
bool vis[maxn];

void dj(int s)
{
	fill(d, d + maxn, inf);
	fill(c, c + maxn, inf);
	d[s] = 0;
	c[s] = 0;
	for (int i = 0; i < n; i++)
	{
		int u = -1, mindis = inf;
		for (int j = 0; j < n; j++)
		{
			if (vis[j] == false && d[j] < mindis)
			{
				u = j;
				mindis = 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] + C[u][v];
					pre[v] = u;
				}
				else if (d[u] + G[u][v] == d[v])
				{
					if (c[u] + C[u][v] < c[v])
					{
						c[v] = c[u] + C[u][v];
						pre[v] = u;
					}
				}
		}
	}
}

void dfs(int u)
{
	if (u == st)
	{
		cout << u << " ";
		return;
	}
	dfs(pre[u]);
	cout << u << " ";
}

int main()
{
	cin >> n >> m >> st >> ed;
	int a, b;
	fill(G[0], G[0] + maxn * maxn, inf);
	for (int i = 0; i < m; i++)
	{
		cin >> a >> b;
		cin >> G[a][b] >> C[a][b];
		G[b][a] = G[a][b];
		C[b][a] = C[a][b];
	}
	dj(st);
	dfs(ed);
	cout << d[ed] << " " << c[ed] << endl;
	return 0;
}

dj+dfs算法
思路:先找出几条最短路径,再根据次级条件判断
这要开一个vector数组存上一个点,因为可能有多个

#include<iostream>
#include<vector>
#include<queue>
#include<stack>
#include<string>
#include<math.h>
#include<algorithm>
#include<map>
#include<cstring>
#include<set>
using namespace std;
const int maxn = 501;
const int inf = 1000000000;
int d[maxn], mincost = inf;
int n, m, st, ed;
bool vis[maxn];
int G[maxn][maxn], C[maxn][maxn];
vector<int>pre[maxn];
vector<int>tempPath, path;

void dj(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) {
		tempPath.push_back(v);
		int tempCost = 0;
		for (int i = tempPath.size() - 1; i > 0; i--)
		{
			int id = tempPath[i], idnext = tempPath[i - 1];
			tempCost += C[id][idnext];
		}
		if (tempCost < mincost)
		{
			mincost = tempCost;
			path = tempPath;
		}
		tempPath.pop_back();
		return;
	}
	tempPath.push_back(v);
	for (int i = 0; i < pre[v].size(); i++)
	{
		dfs(pre[v][i]);
	}
	tempPath.pop_back();
}
int main()
{
	cin >> n >> m >> st >> ed;
	int a, b;
	fill(G[0], G[0] + maxn * maxn, inf);
	for (int i = 0; i < m; i++)
	{
		cin >> a >> b;
		cin >> G[a][b] >> C[a][b];
		G[b][a] = G[a][b];
		C[b][a] = C[a][b];
	}
	dj(st);
	dfs(ed);
	for (int i = path.size() - 1; i >= 0; i--)
	{
		cout << path[i] << " ";
	}
	cout << d[ed] << " " << mincost << endl;
	return 0;
}

原文地址:https://www.cnblogs.com/Hsiung123/p/13811996.html