给定N个节点的无向图,形式为{X,Y,Z}的M个边,使得X和Y之间存在边为Z的边。任务是找到从源节点1到目标节点N的最小开销,这样我们就可以将遍历期间仅一条路径的开销减少2。
例子:
Input: N = 3, M = 4, Edges = {{1, 2, 3}, {2, 3, 1}, {1, 3, 7}, {2, 1, 5}}
Output: 2
Explanation:
Minimum Cost from source node 1 to destination node N is = 3/2 + 1 = 1 + 1 = 2.
Input: N = 3, M = 3, Edges = {{2, 3, 1}, {1, 3, 7}, {2, 1, 5}}
Output: 2
Explanation:
Minimum Cost from source node 1 to destination node N is = 7/2 = 3.
方法:想法是考虑所有优势,并尝试通过降低成本来最大程度地降低总体成本。主要思想是将源到目标的路径分解为源到任何顶点u的路径,即path(1到u),以及从目标到任何顶点v的路径,即所有u和v的路径(n到v)。以下是步骤:
- 执行Dijkstra算法以查找源节点1上所有顶点的单个源最短路径,并将其存储为dist_from_source []数组。
- 执行Dijkstra算法,以查找来自源节点N的所有顶点的单个源最短路径,并将其存储为dist_from_dest []数组。
- 将最小成本(例如minCost )初始化为最大值。
- 遍历给定的边,对于每个边,将当前成本降低一半,并将最小成本更新为:
minCost = min(minCost, dist_from_source[u] + c/2 + dist_from_dest[v])
where,
c is the cost of current edge,
dist_from_source[u] is cost of path from node 1 to u
dist_from_source[v] is cost of path from node v to N - 完成上述步骤后,打印minCost的值。
下面是上述方法的实现:
C++14
// C++ program for the above approach
#include
using namespace std;
#define INF 1e9
// Function for Dijkstra Algorithm to
// find single source shortest path
void dijkstra(int source, int n,
vector >
adj[],
vector& dist)
{
// Resize dist[] to N and assign
// any large value to it
dist.resize(n, INF);
// Initialise distance of source
// node as 0
dist = 0;
// Using min-heap priority_queue
// for sorting wrt edges_cost
priority_queue,
vector >,
greater > >
pq;
// Push the current dist
// and source to pq
pq.push({ dist, source });
// Until priority queue is empty
while (!pq.empty()) {
// Store the cost of linked
// node to edges
int u = pq.top().second;
// int d = pq.top().first;
// Pop the top node
pq.pop();
// Iterate over edges
for (auto& edge : adj[u]) {
// Find the starting and
// ending vertex of edge
int v = edge.first;
int w = edge.second;
// Update the distance of
// node v to minimum of
// dist[u] + w if it is
// minimum
if (dist[u] + w < dist[v]) {
dist[v] = dist[u] + w;
pq.push({ dist[v], v });
}
}
}
}
// Function to find the minimum cost
// between node 1 to node n
void minCostPath(
vector > >& edges,
int n, int M)
{
// To create Adjacency List
vector > adj[100005];
// Iterate over edges
for (int i = 0; i < M; i++) {
// Get source, destination and
// edges of edges[i]
int x = edges[i].first;
int y = edges[i].second.first;
int z = edges[i].second.second;
// Create Adjacency List
adj[x].push_back({ y, z });
adj[y].push_back({ x, z });
}
// To store the cost from node 1
// and node N
vector dist_from_source;
vector dist_from_dest;
// Find the cost of travel between
// source(1) to any vertex
dijkstra(1, n + 1, adj, dist_from_source);
// Find the cost of travel between
// destination(n) to any vertex
dijkstra(n, n + 1, adj, dist_from_dest);
// Initialise the minimum cost
int min_cost = dist_from_source[n];
// Traverse the edges
for (auto& it : edges) {
// Get the edges
int u = it.first;
int v = it.second.first;
int c = it.second.second;
// Find the current cost from
// node 1 to u and node u to v
// and node v to N with only
// current edge cost reduced
// to half
int cur_cost = dist_from_source[u]
+ c / 2
+ dist_from_dest[v];
// Update the min_cost
min_cost = min(min_cost, cur_cost);
}
// Print the minimum cost
cout << min_cost << '\n';
}
// Driver Code
int main()
{
// Give Nodes and Edges
int N = 3;
int M = 3;
// Given Edges with cost
vector > > edges;
edges.push_back({ 2, { 3, 1 } });
edges.push_back({ 1, { 3, 7 } });
edges.push_back({ 2, { 1, 5 } });
// Function Call
minCostPath(edges, N, M);
return 0;
}
3
时间复杂度: O(N + M),其中N是节点数,M是边数。
辅助空间: O(N),其中N是节点数。