Dijkstra---------多标尺问题(Dijkstra解决)

引入问题:

      有N个城市(标号为0-N-1),M条道路(无向边)、并且给出M条道路的距离属性和花费属性。现在给定起点s和终点d,求从起点到终点的最短路径及花费。注意:如果有多条最短路径,则选择花费最小的那条

     下面是核心算法

void Dijkstra(int s)
{
	fill(dis, dis + n, INF);
	fill(c, c + MAXN, INF);
	for (int i = 0; i < n; i++)
		pre[i] = i;
	dis[s] = 0;
	c[s] = 0;
	priority_queue<node> q;
	q.push(node(s, dis[s]));
	while (!q.empty())
	{
		node x = q.top();
		q.pop();
		for (int i = 0; i < Adj[x.x].size(); i++)
		{
			node y = Adj[x.x][i];
			if (dis[y.x] > x.d + y.d)
			{
				dis[y.x] = x.d + y.d;
				c[y.x] = c[x.x] + cost[x.x][y.x];
				pre[y.x] = x.x;
				q.push(node(y.x, dis[y.x]));
			}
			else if (dis[y.x] == x.d + y.d)
			{
				if (c[y.x] > c[x.x] + cost[x.x][y.x])
				{
					c[y.x] = c[x.x] + cost[x.x][y.x];
					pre[y.x] = x.x;
					q.push(node(y.x, dis[y.x]));
				}
			}
		}

	}
}


总代码:

#include<iostream>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
const int MAXN = 510;
const int INF = 100000000;
struct node {
	int x;
	int d;
	node() {}
	node(int a, int b) {
		x = a;
		d = b;
	}
	bool operator < (const node& a)const
	{
		if (d == a.d) return x < a.x;
		else return d > a.d;
	}
};
int cost[MAXN][MAXN];//储存两个结点之间的边权(也就是这里所说的花费)
int c[MAXN];//记录到这个结点的最小花费
vector<node> Adj[MAXN];//储存两个结点的距离
int n, m, s;
int st;//起始结点的位置
int ed;//终点结点的位置
int dis[MAXN];//储存到这个结点的最短距离
int pre[MAXN];//储存最短路线
void Dijkstra(int s)
{
	fill(dis, dis + n, INF);//初始化数组
	fill(c, c + MAXN, INF);
	for (int i = 0; i < n; i++)//将每个元素设置成自己
		pre[i] = i;
	dis[s] = 0;
	c[s] = 0;
	priority_queue<node> q;
	q.push(node(s, dis[s]));
	while (!q.empty())
	{
		node x = q.top();
		q.pop();
		for (int i = 0; i < Adj[x.x].size(); i++)
		{
			node y = Adj[x.x][i];
			if (dis[y.x] > x.d + y.d)
			{
				dis[y.x] = x.d + y.d;
				c[y.x] = c[x.x] + cost[x.x][y.x];//更新最小花费值
				pre[y.x] = x.x;//更新当前结点的上一个结点是x.x
				q.push(node(y.x, dis[y.x]));
			}
			else if (dis[y.x] == x.d + y.d)
			{
				if (c[y.x] > c[x.x] + cost[x.x][y.x])
				{
					c[y.x] = c[x.x] + cost[x.x][y.x];//更新最小花费
					pre[y.x] = x.x;
					q.push(node(y.x, dis[y.x]));
				}
			}
		}
	}
}
void DFS(int v)//递归,打印出路线
{
	if (v == st)
	{
		cout << v << " " ;
		return;
	}
	DFS(pre[v]);
	cout << v << " ";
}
int main()
{
	cin >> n >> m >> st >> ed;//n是结点数,m是边数,st是起始结点编号,ed是终点编号
	int u, v, w;
	for (int i = 0; i < m; i++)
	{
		cin >> u >> v >> w;
		cin >> cost[u][v];
		Adj[u].push_back(node(v, w));
		Adj[v].push_back(node(u, w));
	}
	Dijkstra(st);
	DFS(ed);//从终点结点编号出发
	cout << dis[ed] << " " << c[ed];
	system("pause");
	return 0;
}

猜你喜欢

转载自blog.csdn.net/scwmason/article/details/80970476
今日推荐