c_cpp needtodo在无向图中找到两个给定节点之间的第二条最短路径

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c_cpp needtodo在无向图中找到两个给定节点之间的第二条最短路径相关的知识,希望对你有一定的参考价值。


/*
Supposing we're finding the second shortest path between 2 nodes A and B, start by finding the shortest path from A to all the other nodes using Dijkstra's algorithm. Do the same for node B.

Supposing the second shortest path can have the same length as the shortest path (a different edge), mark the edges of the shortest path found in the first Dijkstra. Now process the vertices used in the shortest path, for each one, try to use an edge, other than the one of the shortest path and check the distance from A to this vertex + weight of this edge + distance from this edge to B (using the values from the second Dijkstra).
*/

struct Edge {
	int next, weight;
	bool used;
	Edge(int v = 0 , int w = 0) {
		next=  v, weight = w;
		used = false;
	}
};
vector<Edge> ugraph[MAX];
int distA[MAX], distB[MAX];
 
void dijkstraAlgorithm(int N, int s, int dist[MAX]) {
	int i;
	for (i = 0 ; i < N ; i++)
		dist[i] = 100000000;		// infinity
	dist[s] = 0;
	set<pair<int,int> > heap;
	heap.insert(make_pair(0,s));
 
	while (heap.size()) {
		pair<int,int> cur = *heap.begin(); 
		heap.erase( heap.begin());
		int v = cur.second, d = -cur.first;
		vector<Edge>::iterator it;
		for ( it = ugraph[v].begin() ; it != ugraph[v].end(); it++) {
			int tdist = d + it->weight;
			if (tdist < dist[it->next] ) {
				heap.erase( make_pair( -dist[it->next] , it->next  ));
				dist[it->next] = tdist;
				heap.insert( make_pair( -tdist , it->next  ));
			}
		}
	}
}
void findSecondShortestPath(int N, int A, int B) {
	dijkstraAlgorithm(N, A, distA);
	dijkstraAlgorithm(N, B, distB);
 
	int v = A, bestCost = distA[B];
	vector<Edge>::iterator it;
	vector<int> bestPath;
	while (v != B) {			// mark the shortest path
		bestPath.push_back(v);
		for ( it = ugraph[v].begin() ; it != ugraph[v].end(); it++) 
			if (distA[v] + it->weight + distB[ it->next ] == bestCost ) {
				it->used = true;				
				v = it->next;
				break;
			}
	}
	int second = 100000000 , next, turningPoint,t;
	v = A;			// find the second best cost and identify the 
	while (v != B) {	// turning point from the best path
		for ( it = ugraph[v].begin() ; it != ugraph[v].end(); it++) 
			if (it->used == false) {
				t = distA[v] + it->weight + distB[ it->next ];
				if (second > t) {
					second = t;
					turningPoint = v;
				}
			}
			else
				next = it->next;
		v = next;
	}
	printf("Second best = %d\n", second );
	for (v = 0 ; bestPath[v] != turningPoint ; v++)
		printf("%d ", bestPath[v]);
	v = turningPoint;
	printf("%d ", v);	// print path
	while (v != B) {
		for ( it = ugraph[v].begin() ; it != ugraph[v].end(); it++) 
			if (distA[v] + it->weight + distB[ it->next ] == second ) {
				printf("%d ", it->next);
				v = it->next;
				break;
			}
	}
	putchar('\n');
}

以上是关于c_cpp needtodo在无向图中找到两个给定节点之间的第二条最短路径的主要内容,如果未能解决你的问题,请参考以下文章

c_cpp 在无向和连通图中的长度为n的循环

在两个顶点之间的无向图中查找特定边

以最小成本断开无向加权图中的两个节点

text 给定无向图G =(V,E),其中V是非空集合,称为顶点集; E是V中元素构成的无序二元组的集合,称为边集,无向图中的边均是顶点的无序对,无序对常用圆括号“()”表示。如果U∈V,且对任意两个

text 给定无向图G =(V,E),其中V是非空集合,称为顶点集; E是V中元素构成的无序二元组的集合,称为边集,无向图中的边均是顶点的无序对,无序对常用圆括号“()”表示。如果U∈V,且对任意两个

去除最少边以强制增加未加权无向图中最短路径长度的算法