📌  相关文章
📜  反转边的最小成本,使得每对节点之间都有路径

📅  最后修改于: 2021-10-25 05:06:55             🧑  作者: Mango

给定一个连通的有向图。每个节点正好连接到另外两个节点。与每条边相关的权重表示反转其方向的成本。任务是找到反转图的某些边的最小成本,以便可以从每个节点到每个其他节点。
例子:

Input: 
5
1 2 7
5 1 8
5 4 5
3 4 1
3 2 10
Output: 15

Input:
6
1 5 4
5 3 8
2 4 15
1 6 16
2 3 23
4 6 42
Output: 39

方法:

  • 为了从每个节点到达每个其他节点,该图必须形成一个环,即沿顺时针或逆时针方向的 2 个方向之一定向其上的所有边。让我们将所有顺时针边缘重定向到逆时针方向的成本表示为 cost1,反之亦然为 cost2。答案显然是这两个成本中的最小值。
  • 维护两个布尔数组开始和结束。 start 和 end 数组表示是否存在从给定节点开始或结束的边。每当我们遇到从节点 a 到节点 b 的边时,我们首先检查条件是否存在从节点 a 开始或在节点 b 结束的边。如果存在满足条件的边,则该边与已经存在的边方向相反。在这种情况下,我们更新 cost2 并将边缘存储在相反的方向。否则,我们更新cost1。这样我们就能够维持两个方向的成本。最后,打印最低成本。

下面是上述方法的实现:

C++
// C++ code to find
// the minimum cost to
// reverse the edges
#include 
using namespace std;
 
// Function to calculate
// min cost for reversing
// the edges
int minCost(vector >& graph, int n)
{
 
    int cost1 = 0, cost2 = 0;
    // bool array to mark
    // start and end node
    // of a graph
    bool start[n + 1] = { false };
    bool end[n + 1] = { false };
 
    for (int i = 0; i < n; i++) {
 
        int a = graph[i][0];
        int b = graph[i][1];
        int c = graph[i][2];
 
        // This edge must
        // start from b and end at a
        if (start[a] || end[b]) {
            cost2 += c;
            start[b] = true;
            end[a] = true;
        }
 
        // This edge must
        // start from a and end at b
        else {
            cost1 += c;
            start[a] = true;
            end[b] = true;
        }
    }
 
    // Return minimum of
    // both possibilities
    return min(cost1, cost2);
}
 
// Driver code
int main()
{
    int n = 5;
    // Adjacency list representation
    // of a graph
    vector > graph = {
        { 1, 2, 7 },
        { 5, 1, 8 },
        { 5, 4, 5 },
        { 3, 4, 1 },
        { 3, 2, 10 }
    };
 
    int ans = minCost(graph, n);
    cout << ans << '\n';
 
    return 0;
}


Java
// Java code to find the minimum cost to
// reverse the edges
class GFG
{
 
// Function to calculate min cost for
// reversing the edges
static int minCost(int[][] graph, int n)
{
 
    int cost1 = 0, cost2 = 0;
     
    // bool array to mark start and
    // end node of a graph
    boolean []start = new boolean[n + 1];
    boolean []end = new boolean[n + 1];
 
    for (int i = 0; i < n; i++)
    {
        int a = graph[i][0];
        int b = graph[i][1];
        int c = graph[i][2];
 
        // This edge must start from b
        // and end at a
        if (start[a] || end[b])
        {
            cost2 += c;
            start[b] = true;
            end[a] = true;
        }
 
        // This edge must start from a
        // and end at b
        else
        {
            cost1 += c;
            start[a] = true;
            end[b] = true;
        }
    }
 
    // Return minimum of both possibilities
    return Math.min(cost1, cost2);
}
 
// Driver code
public static void main(String[] args)
{
    int n = 5;
     
    // Adjacency list representation
    // of a graph
    int [][]graph = {{ 1, 2, 7 },
                     { 5, 1, 8 },
                     { 5, 4, 5 },
                     { 3, 4, 1 },
                     { 3, 2, 10 }};
 
    int ans = minCost(graph, n);
    System.out.println(ans);
}
}
 
// This code is contributed by Rajput-Ji


Python3
# Python code to find the minimum cost to
# reverse the edges
 
# Function to calculate min cost for
# reversing the edges
def minCost(graph, n):
 
    cost1, cost2 = 0, 0;
     
    # bool array to mark start and
    # end node of a graph
    start = [False]*(n + 1);
    end = [False]*(n + 1);
 
    for i in range(n):
        a = graph[i][0];
        b = graph[i][1];
        c = graph[i][2];
 
        # This edge must start from b
        # and end at a
        if (start[a] or end[b]):
            cost2 += c;
            start[b] = True;
            end[a] = True;
 
        # This edge must start from a
        # and end at b
        else:
            cost1 += c;
            start[a] = True;
            end[b] = True;
 
    # Return minimum of both possibilities
    return min(cost1, cost2);
 
# Driver code
if __name__ == '__main__':
    n = 5;
     
    # Adjacency list representation
    # of a graph
    graph = [[ 1, 2, 7 ],
                    [ 5, 1, 8 ],
                    [ 5, 4, 5 ],
                    [ 3, 4, 1 ],
                    [ 3, 2, 10 ]];
 
    ans = minCost(graph, n);
    print(ans);
     
# This code is contributed by 29AjayKumar


C#
// C# code to find the minimum cost to
// reverse the edges
using System;
     
class GFG
{
 
// Function to calculate min cost for
// reversing the edges
static int minCost(int[,] graph, int n)
{
    int cost1 = 0, cost2 = 0;
     
    // bool array to mark start and
    // end node of a graph
    Boolean []start = new Boolean[n + 1];
    Boolean []end = new Boolean[n + 1];
 
    for (int i = 0; i < n; i++)
    {
        int a = graph[i, 0];
        int b = graph[i, 1];
        int c = graph[i, 2];
 
        // This edge must start from b
        // and end at a
        if (start[a] || end[b])
        {
            cost2 += c;
            start[b] = true;
            end[a] = true;
        }
 
        // This edge must start from a
        // and end at b
        else
        {
            cost1 += c;
            start[a] = true;
            end[b] = true;
        }
    }
 
    // Return minimum of both possibilities
    return Math.Min(cost1, cost2);
}
 
// Driver code
public static void Main(String[] args)
{
    int n = 5;
     
    // Adjacency list representation
    // of a graph
    int [,]graph = {{ 1, 2, 7 },
                    { 5, 1, 8 },
                    { 5, 4, 5 },
                    { 3, 4, 1 },
                    { 3, 2, 10 }};
 
    int ans = minCost(graph, n);
    Console.WriteLine(ans);
}
}
 
// This code is contributed by PrinciRaj1992


Javascript


输出:
15

时间复杂度: O(N),其中 N 是边数

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