单源/多源最短路径

文章目录

  • 单源最短路径
    • 单源无权最短路径
    • 有权图的单源最短路算法 Dijstra
  • 多源最短路径 Floyd

单源最短路径

  • 单源即一个起点,指从图中某个结点开始到其他所有结点

单源无权最短路径

关于本例中图的邻接矩阵创建参见 图的深搜和广搜

int dist[MAX_VERTEX];
int path[MAX_VERTEX];

void unWeightedSP(int v)
{
	for (int i = 0; i < nv; ++i) {
		dist[i] = -1;
	}
	dist[v] = 0;
	queue<int> q;
	q.push(v);
	while (!q.empty()) {
		int u = q.front();
		q.pop();
		for (int j = 0; j < nv; ++j) {
			if (MGraph[u][j] == 1&& dist[j] == -1) {
				dist[j] = dist[u] + 1;
				path[j] = u;
				q.push(j);
			}
		}
	}
}

有权图的单源最短路算法 Dijstra

Dijkstra算法
单源/多源最短路径_第1张图片

void Dijsktra(int v)
{
	int i;
	//初始化
	for (i = 0; i < nv; ++i) {
		dist[i] = 9999;
		path[i] = -1;
	}
	dist[v] = 0;

	while (1) {
		//获取未收录结点中距离源点距离最小者
		int u = getMinDistV();
		if (u == -1)break;//循环退出条件
		collected[u] = 1;
		//依次遍历u的邻接点
		for (int j = 0; j < nv; ++j) {
			if ((MGraph[u][j] > 0) && (collected[j] == 0)) {
				if (dist[u] + MGraph[u][j] < dist[j]) {
					dist[j] = dist[u] + MGraph[u][j];
					path[j] = u;
				}
			}
		}
	}
}
int getMinDistV()
{
	int i;
	int minDist = 9999;
	int minV = -1;
	for (i = 0; i < nv; ++i) {
		if ((minDist > dist[i])&&(collected[i]==0)) {
			minDist = dist[i];
			minV = i;
		}
	}
	return minV;
}
  • Full Code

    #include
    #include
    
    using namespace std;
    
    #define MAX_VERTEX 100
    
    int MGraph[MAX_VERTEX][MAX_VERTEX];
    int visit[MAX_VERTEX];
    
    int nv, ne;
    void creatMGraph();
    void printMGraph();
    void Dijsktra(int v);
    int getMinDistV();
    int dist[MAX_VERTEX];
    int collected[MAX_VERTEX];
    int path[MAX_VERTEX];
    
    int main()
    {	
    	creatMGraph();
    	printMGraph();
    	Dijsktra(0);
    	for (int i = 0; i < nv; ++i)cout << dist[i] << " ";
    	system("pause");
    	return 0;
    }
    void creatMGraph()
    {
    	cout << "请输入结点数nv: ";
    	cin >> nv;
    	//初始化
    	int i, j;
    	for (i = 0; i < nv; ++i) {
    		visit[i] = 0;	
    	}
    	for (i = 0; i < nv; ++i) {
    		for (j = 0; j < nv; ++j) {
    			MGraph[i][j] = 0;
    		}
    	}
    	//添加边
    	cout << "请输入边数ne:";
    	cin >> ne;
    	cout << "请依次输入边及权重(例如:3 1 2): " << endl;
    	int w;
    	for (int k = 0; k < ne; ++k) {
    		cin >> i >> j >> w;
    		MGraph[i][j] = w;
    	}
    }
    void printMGraph()
    {
    	int i, j;
    	for (i = 0; i < nv; ++i) {
    		for (j = 0; j < nv; ++j) {
    			cout << MGraph[i][j] << " ";
    		}
    		cout << endl;
    	}
    }
    void Dijsktra(int v)
    {
    	int i;
    	//初始化
    	for (i = 0; i < nv; ++i) {
    		dist[i] = 9999;
    		path[i] = -1;
    	}
    	dist[v] = 0;
    
    	while (1) {
    		//获取未收录结点中距离源点距离最小者
    		int u = getMinDistV();
    		if (u == -1)break;//循环退出条件
    		collected[u] = 1;
    		//依次遍历u的邻接点
    		for (int j = 0; j < nv; ++j) {
    			if ((MGraph[u][j] > 0) && (collected[j] == 0)) {
    				if (dist[u] + MGraph[u][j] < dist[j]) {
    					dist[j] = dist[u] + MGraph[u][j];
    					path[j] = u;
    				}
    			}
    		}
    	}
    }
    int getMinDistV()
    {
    	int i;
    	int minDist = 9999;
    	int minV = -1;
    	for (i = 0; i < nv; ++i) {
    		if ((minDist > dist[i])&&(collected[i]==0)) {
    			minDist = dist[i];
    			minV = i;
    		}
    	}
    	return minV;
    }
    

多源最短路径 Floyd

  • 多源即图中任意两个结点
    单源/多源最短路径_第2张图片
void Floyd()
{
	int i, j, k;
	for (i = 0; i < nv; ++i) {
		for (j = 0; j < nv; ++j) {
			Dist[i][j] = MGraph[i][j] > 0 ? MGraph[i][j] : 9999;
			Path[i][j] = -1;
		}
	}
	for (k = 0; k < nv; ++k) {
		for (i = 0; i < nv; ++i) {
			for (j = 0; j < nv; ++j) {
				if (Dist[i][k] + Dist[k][j] < Dist[i][j]) {
					Dist[i][j] = Dist[i][k] + Dist[k][j];
					Path[i][j] = k;
				}
			}
		}
	}
}

你可能感兴趣的:(数据结构与算法,算法,数据结构)