📜  反转边缘的最低成本,使得每对节点之间都有路径

📅  最后修改于: 2021-04-23 20:54:14             🧑  作者: Mango

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

例子:

输入: 5 1 2 7 5 1 8 5 4 5 3 4 1 3 2 10输出: 15 输入: 6 1 5 4 5 3 8 2 4 15 1 6 16 2 3 23 4 6 42输出: 39

方法:

  • 为了从每个节点到达每个其他节点,图必须形成一个环,即沿顺时针方向或逆时针方向将其所有边沿2个方向之一引导。让我们将将所有顺时针边沿重定向到逆时针方向的成本表示为cost1,反之亦然,将其表示为cost2。答案显然是这两个成本中的最小值。
  • 保持两个布尔数组开始和结束。开始和结束数组表示是否存在从给定节点开始或结束的边。每当遇到从节点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 posibilities
    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 posibilities
    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 posibilities
    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 posibilities
    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


输出:
15

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