[DOJ练习] (Dijkstra溯源)使用邻接矩阵实现有向图最短路径Dijkstra算法

嘿嘿,第一个AC ...

 用邻接矩阵存储有向图,实现最短路径Dijkstra算法,图中边的权值为整型,顶点个数少于10个。

部分代码提示:

#include <iostream>
#include <string>

using namespace std;

const int MaxSize = 10;
const int INF = 32767;

class MGraph
{
	public:
		MGraph(char a[], int n, int e);
		void Dijkstra();
	private:
		char vertex[MaxSize];
		int arc[MaxSize][MaxSize];
		int vertexNum, arcNum;
};

MGraph::MGraph(char a[], int n, int e)
{
//write your code.

}

int Min(int dist[], int vertexNum)
{
//write your code.

}

void MGraph::Dijkstra()
{
//write your code.

}

int main()
{
	int n = 0;
	int e = 0;
	cin >> n >> e;
	char p[MaxSize];
	int i = 0;
	for (i=0; i<n; i++)
	{
		cin >> p[i];
	}

	MGraph MG(p, n, e);

	MG.Dijkstra();

	return 0;

}

输入描述

首先输入图中顶点个数和边的条数;
再输入顶点的信息(字符型);
再输入各边及其权值。

输出描述

依次输出从编号为0的顶点开始的从小到大的所有最短路径,每条路径及其长度占一行。

输入样例

5 7
A B C D E
0 1 6
0 2 2
0 3 1
1 2 4
1 3 3
2 4 6
3 4 7


输出样例

AD 1
AC 2
AB 6
ADE 8

此题除了考验朴素版dijkstra, 还需要路径排序,溯源..

溯源利用递归,以及pre数组(和并查集相似)

各种路径排序,可以用结构体或者vector来存储路径以及长度

注意:本校OJ请自行删除所有换行

#include <iostream>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;

typedef pair<int, int> PII;
vector<PII> v;
const int MaxSize = 10;
const int INF = 0x3f3f3f3f;
int st[MaxSize];

class MGraph
{
public:
	int dist[MaxSize];
	MGraph(char a[], int n, int e);
	
	void Dijkstra(int goal);
	void showLenthRank();
	void shortMinPath(int pre[], int u);
private:
	char vertex[MaxSize];
	int arc[MaxSize][MaxSize];
	int vertexNum, arcNum;
};

MGraph::MGraph(char a[], int n, int e)
{
	vertexNum = n, arcNum = e;
	memset(dist, 0x3f, sizeof dist);
	memset(arc, 0x3f, sizeof arc);
	
	for(int i = 0; i < vertexNum; i++){
		vertex[i] = a[i];
	}
	
	int x,y,w;
	for(int i = 0; i < arcNum; i++)
	{
		cin >> x >> y >> w;
		arc[x][y] = w;
	} 
}

void MGraph::Dijkstra(int goal)
{
	memset(dist, 0x3f, sizeof dist);
	dist[0] = 0;
	
	for(int i = 0; i < vertexNum; i++)
	{
		int t = -1;
		for(int j = 0; j < vertexNum; j++)
			if(!st[j] && (t==-1 || dist[j]<dist[t]))
				t = j;
			
		st[t] = 1;
		for(int j = 0; j < vertexNum; j++)
			dist[j] = min(dist[j], dist[t]+arc[t][j]);
	}
	
	for (int i=1; i<vertexNum; i++)
	{
		v.push_back({dist[i],i});
	}
	sort(v.begin(), v.end());
//	for(int i = 0; i < v.size(); i++){
//		cout << v[i].first << ' ' << v[i].second << endl;
//	}
}

void MGraph::showLenthRank()
{

	for(int k = 0; k < v.size(); k++)
	{
		int pre[MaxSize];
		memset(st, 0, sizeof st);
		memset(dist, 0x3f, sizeof dist);
		dist[0] = 0;
		for(int i = 0; i < vertexNum; i++)
		{
			int t = -1;
			for(int j = 0; j < vertexNum; j++)
				if(!st[j] && (t==-1 || dist[j]<dist[t]))
					t = j;
				
			st[t] = 1;
			//cout << vertex[t];
			if(t == v[k].second){//小优化
				break;
			}
			for(int j = 0; j < vertexNum; j++)
			{
				if(!st[j] &&dist[t]+arc[t][j] < dist[j]){
					dist[j] = dist[t]+arc[t][j];
					pre[j] = t;
				}
			}	
		}
		shortMinPath(pre,v[k].second);
		cout << ' '<< v[k].first << endl;
	}
}

void MGraph::shortMinPath(int pre[], int u)
{
	if(u == 0){
		cout << vertex[0];
		return ;
	}
	shortMinPath(pre, pre[u]);
	cout << vertex[u];
}

int main()
{
	int n = 0;
	int e = 0;
	cin >> n >> e;
	char p[MaxSize];
	int i = 0;

	for (i=0; i<n; i++)
	{
		cin >> p[i];
	}

	MGraph MG(p, n, e);
	
	MG.Dijkstra(n-1);
	
	MG.showLenthRank();

	return 0;
}

原文地址:https://www.cnblogs.com/Knight02/p/15799045.html