给定无向加权图。任务是找到通过中间节点从源节点到目标节点的路径的最小开销。
注意:如果一条边缘移动了两次,则仅计算一次重量作为成本。
例子:
Input: source = 0, destination = 2, intermediate = 3;
Output: 6
The minimum cost path 0->1->3->1->2
The edge (1-3) occurs twice in the path, but its weight is
added only once to the answer.
Input: source = 0, destination = 2, intermediate = 1;
Output: 3
The minimum cost path is 0->1>2
方法:假设采用从源到中间的路径P1,以及从中间到目标的路径P2。这两个路径之间可能有一些共同的边缘。因此,最佳路径将始终具有以下形式:对于任何节点U,步行都包括从源到U,从中间到U,从目的地到U的最短路径上的边。因此,如果dist(a,b )是节点a和b之间最短路径的成本,所需的最小成本路径将是min {dist(Source,U)+ dist(intermediate,U)+ dist(destination,U)} 对于所有U。通过对这3个节点执行Dijkstra的最短路径算法,可以找到所有节点距源,中间和目标的最小距离。
下面是上述方法的实现。
CPP
// CPP program to find minimum distance between
// source and destination node and visiting
// of intermediate node is compulsory
#include
using namespace std;
#define MAXN 100005
// to store maped values of graph
vector > v[MAXN];
// to store distance of
// all nodes from the source node
int dist[MAXN];
// Dijkstra's algorithm to find
// shortest path from source to node
void dijkstra(int source, int n)
{
// set all the vertices
// distances as infinity
for (int i = 0; i < n; i++)
dist[i] = INT_MAX;
// set all vertex as unvisited
bool vis[n];
memset(vis, false, sizeof vis);
// make distance from source
// vertex to source vertex is zero
dist = 0;
// // multiset do the job
// as a min-priority queue
multiset > s;
// insert the source node with distance = 0
s.insert({ 0, source });
while (!s.empty()) {
pair p = *s.begin();
// pop the vertex with the minimum distance
s.erase(s.begin());
int x = p.second;
int wei = p.first;
// check if the popped vertex
// is visited before
if (vis[x])
continue;
vis[x] = true;
for (int i = 0; i < v[x].size(); i++) {
int e = v[x][i].first;
int w = v[x][i].second;
// check if the next vertex
// distance could be minimized
if (dist[x] + w < dist[e]) {
dist[e] = dist[x] + w;
// insert the next vertex
// with the updated distance
s.insert({ dist[e], e });
}
}
}
}
// function to add edges in graph
void add_edge(int s, int t, int weight)
{
v[s].push_back({ t, weight });
v[t].push_back({ s, weight });
}
// function to find the minimum shortest path
int solve(int source, int destination,
int intermediate, int n)
{
int ans = INT_MAX;
dijkstra(source, n);
// store distance from source to
// all other vertices
int dsource[n];
for (int i = 0; i < n; i++)
dsource[i] = dist[i];
dijkstra(destination, n);
// store distance from destination
// to all other vertices
int ddestination[n];
for (int i = 0; i < n; i++)
destination[i] = dist[i];
dijkstra(intermediate, n);
// store distance from intermediate
// to all other vertices
int dintermediate[n];
for (int i = 0; i < n; i++)
dintermediate[i] = dist[i];
// find required answer
for (int i = 0; i < n; i++)
ans = min(ans, dsource[i] + ddestination[i]
+ dintermediate[i]);
return ans;
}
// Driver code
int main()
{
int n = 4;
int source = 0, destination = 2, intermediate = 3;
// add edges in graph
add_edge(0, 1, 1);
add_edge(1, 2, 2);
add_edge(1, 3, 3);
// function call for minimum shortest path
cout << solve(source, destination, intermediate, n);
return 0;
}
6
时间复杂度: O((N + M)* logN),其中N是节点数,M是边数。
辅助空间: O(N + M)
如果您希望与行业专家一起参加现场课程,请参阅《 Geeks现场课程》和《 Geeks现场课程美国》。