📌  相关文章
📜  通过将边的权重减半,图中两个节点之间的最短距离

📅  最后修改于: 2021-10-25 03:17:30             🧑  作者: Mango

给定一个由N 个节点和M 个边组成的加权无向图,任务是通过将一条边的权重减半来找到两个节点AB之间的最短距离。

例子:

方法:给定的问题可以通过维护两个数组来解决,最短距离数组以源节点为 A 存储所有节点到A的最短距离,同样最短距离数组以源节点为B 。可以使用 Dijkstra 算法计算这些数组。请按照以下步骤解决上述问题:

  • 使用 Dijkstra 算法将每个节点到A的最短距离存储到数组disA[] 中
  • 使用 Dijkstra 算法将每个节点到B的最短距离存储到数组disB[] 中
  • 假设边i = {u i , v i , wt i },即边i将节点u i连接到v i并且权重为wt i
  • 现在,迭代所有边,并为每条边跟踪函数:
  • 上述关系给出了f(edge)的最小值,即由此产生的最短距离。

下面是上述方法的实现:

C++14
// C++ program for the above approach
  
#include 
using namespace std;
  
// Stores the input Graph
vector > graph[100001];
  
// Stores edges of input Graph
vector > edges;
  
// Function to input Edges
void add_edge(int u, int v, int w)
{
    graph[u].push_back({ v, w });
    graph[v].push_back({ u, w });
    edges.push_back({ u, v, w });
}
  
// Function to find the shortest distance
// to each node from the src node using
// Dijkstra’s Algorithm
vector dijsktras(int src, int N)
{
    // Stores the shortest distance of
    // each node form src node
    vector dis(N, INT_MAX);
  
    vector vis(N, false);
  
    // Stores the node and currrent
    // minimum distance in a heap
    priority_queue,
                   vector >,
                   greater > >
        pq;
    pq.push({ 0, src });
    dis[src] = 0;
  
    // BFS for single source shortest
    // path algorithm
    while (!pq.empty()) {
  
        // Top of the PQ
        auto cur = pq.top();
        pq.pop();
  
        // Store the node and weight
        int node = cur.second;
        int weight = cur.first;
  
        // If node is already visited
        if (vis[node])
            continue;
        vis[node] = true;
  
        // Traverse the adjacency list
        // of the node
        for (auto child : graph[node]) {
  
            // If the distance obtained
            // from parent is less than
            // the current minimum
            // distance stored for child
            if (dis[child.first]
                > child.second + weight) {
                dis[child.first] = weight
                                   + child.second;
  
                // Push the next pair
                // in the PQ
                pq.push({ dis[child.first],
                          child.first });
            }
        }
    }
  
    // Return the maximum distance
    return dis;
}
  
// Function to find shortest distance
// between two nodes by reducing any
// one weight of an edge by half
int shortestDistance(int N, int M,
                     int A, int B)
{
    // Stores the the shortest distance
    // of each node from A
    vector disA = dijsktras(A, N);
  
    // Stores the the shortest distance
    // of each node from B
    vector disB = dijsktras(B, N);
  
    int ans = disA[B];
    for (auto edge : edges) {
        int u = edge[0], v = edge[1];
        int weight = edge[2];
  
        // Calculate the value of f(edge)
        // for the current edge
        int cur = min(disA[u] + disB[v],
                      disA[v] + disB[u])
                  + (weight / 2);
  
        // Keep track of the mimimum of
        // f(edge) for all edges
        ans = min(ans, cur);
    }
  
    // Return Answer
    return ans;
}
  
// Driver Code
int main()
{
    int N = 9, M = 14, A = 0, B = 2;
  
    // Create a Graph
    add_edge(0, 1, 4);
    add_edge(1, 2, 8);
    add_edge(2, 3, 7);
    add_edge(3, 4, 9);
    add_edge(4, 5, 10);
    add_edge(5, 6, 2);
    add_edge(6, 7, 1);
    add_edge(7, 0, 8);
    add_edge(1, 7, 11);
    add_edge(7, 8, 7);
    add_edge(2, 8, 2);
    add_edge(6, 8, 6);
    add_edge(2, 5, 4);
    add_edge(3, 5, 14);
  
    // Function Call
    cout << shortestDistance(N, M, A, B);
  
    return 0;
}


输出:
8

时间复杂度: O(M*log N)
辅助空间: O(N + M)

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程