📜  添加欧拉电路所需的最小边

📅  最后修改于: 2022-05-13 01:57:54.356000             🧑  作者: Mango

添加欧拉电路所需的最小边

给定一个由n 个节点和m个边组成的无向图。任务是找到在给定图中制作欧拉电路所需的最小边。

例子:

输入:n = 3,m = 2 Edges[] = {{1, 2}, {2, 3}} 输出:1 添加欧拉电路所需的最小边通过连接 1 到 3,我们可以创建一个欧拉电路。

对于图中存在的欧拉回路,我们要求每个节点都应该具有偶数度,因为这样就存在一条边,可用于在进入该节点后退出该节点。

现在,可能有两种情况:
1.图中有一个连通分量
在这种情况下,如果图中的所有节点都是偶数,那么我们说该图已经有一个欧拉回路,我们不需要在其中添加任何边。但是如果有任何奇数度的节点,我们需要添加边。
图中可以有偶数个奇数度的顶点。这可以通过以下事实轻松证明:偶数度节点的度数和奇数度数节点的度数之和应该与总度数相匹配,总度数始终为偶数,因为每条边都对该总和贡献了两个。现在,如果我们将图中的随机奇数度节点配对并在它们之间添加一条边,我们可以使所有节点具有偶数度,从而使欧拉电路存在。

2.图中有断开的组件
我们首先将组件标记为奇数和偶数。奇数分量是指其中至少有一个奇数度节点的分量。取出所有偶数组件,从每个组件中选择一个随机顶点并将它们线性排列。现在我们在相邻顶点之间添加一条边。所以我们连接了偶数分量,并制作了一个等效的奇数分量,它有两个奇数度的节点。
现在来处理奇数组件,即具有至少一个奇数度节点的组件。我们可以使用数量等于断开组件数量的边连接所有这些奇数组件。这可以通过按循环顺序放置组件并从每个组件中选择两个奇数度节点并使用它们连接到任一侧的组件来完成。现在我们有一个我们已经讨论过的连接组件。

下面是这种方法的实现:

C++
// C++ program to find minimum edge required
// to make Euler Circuit
#include 
using namespace std;
  
// Depth-First Search to find a connected
// component
void dfs(vector g[], int vis[], int odd[],
                    int deg[],  int comp, int v)
{
    vis[v] = 1;
  
    if (deg[v]%2 == 1)
        odd[comp]++;
  
    for (int u : g[v])
        if (vis[u] == 0)
            dfs(g, vis, odd, deg, comp, u);
}
  
// Return minimum edge required to make Euler
// Circuit
int minEdge(int n, int m, int s[], int d[])
{
    // g : to store adjacency list
    //     representation of graph.
    // e : to store list of even degree vertices
    // o : to store list of odd degree vertices
    vector g[n+1], e, o;
  
    int deg[n+1];  // Degrees of vertices
    int vis[n+1];  // To store visited in DFS
    int odd[n+1];  // Number of odd nodes in components
    memset(deg, 0, sizeof(deg));
    memset(vis, 0, sizeof(vis));
    memset(odd, 0, sizeof(odd));
  
    for (int i = 0; i < m; i++)
    {
        g[s[i]].push_back(d[i]);
        g[d[i]].push_back(s[i]);
        deg[s[i]]++;
        deg[d[i]]++;
    }
  
    // 'ans' is result and 'comp' is component id
    int ans = 0, comp = 0;
    for (int i = 1; i <= n; i++)
    {
        if (vis[i]==0)
        {
            comp++;
            dfs(g, vis, odd, deg, comp, i);
  
            // Checking if connected component
            // is odd.
            if (odd[comp] == 0)
                e.push_back(comp);
  
            // Checking if connected component
            // is even.
            else
                o.push_back(comp);
        }
    }
  
    // If whole graph is a single connected
    // component with even degree.
    if (o.size() == 0 && e.size() == 1)
        return 0;
  
    // If all connected component is even
    if (o.size() == 0)
        return e.size();
  
    // If graph have atleast one even connected
    // component
    if (e.size() != 0)
        ans += e.size();
  
    // For all the odd connected component.
    for (int i : o)
        ans += odd[i]/2;
  
    return ans;
}
  
// Driven Program
int main()
{
    int n = 3, m = 2;
    int source[] = { 1, 2 };
    int destination[] = { 2, 3 };
  
    cout << minEdge(n, m, source, destination) << endl;
    return 0;
}


Java
// Java program to find minimum edge
// required to make Euler Circuit
import java.io.*;
import java.util.*;
  
class GFG 
{
  
    // Depth-First Search to find 
    // a connected component
    static void dfs(Vector[] g, int[] vis, 
                              int[] odd, int[] deg,
                              int comp, int v) 
    {
        vis[v] = 1;
        if (deg[v] % 2 == 1)
            odd[comp]++;
        for (int u : g[v])
            if (vis[u] == 0)
                dfs(g, vis, odd, deg, comp, u);
    }
  
    // Return minimum edge required 
    // to make Euler Circuit
    static int minEdge(int n, int m, 
                       int[] s, int[] d)
    {
  
        // g : to store adjacency list
        //     representation of graph.
        // e : to store list of even degree vertices
        // o : to store list of odd degree vertices
        @SuppressWarnings("unchecked")
        Vector[] g = new Vector[n + 1];
        Vector e = new Vector<>();
        Vector o = new Vector<>();
  
        for (int i = 0; i < n + 1; i++)
            g[i] = new Vector<>();
  
        // Degrees of vertices
        int[] deg = new int[n + 1]; 
          
        // To store visited in DFS
        int[] vis = new int[n + 1];
          
        // Number of odd nodes in components
        int[] odd = new int[n + 1]; 
        Arrays.fill(deg, 0);
        Arrays.fill(vis, 0);
        Arrays.fill(odd, 0);
  
        for (int i = 0; i < m; i++) 
        {
            g[s[i]].add(d[i]);
            g[d[i]].add(s[i]);
            deg[s[i]]++;
            deg[d[i]]++;
        }
  
        // 'ans' is result and 
        // 'comp' is component id
        int ans = 0, comp = 0;
        for (int i = 1; i <= n; i++) 
        {
            if (vis[i] == 0) 
            {
                comp++;
                dfs(g, vis, odd, deg, comp, i);
  
                // Checking if connected component
                // is odd.
                if (odd[comp] == 0)
                    e.add(comp);
  
                // Checking if connected component
                // is even.
                else
                    o.add(comp);
            }
        }
          
        // If whole graph is a single connected
        // component with even degree.
        if (o.size() == 0 && e.size() == 1)
            return 0;
  
        // If all connected component is even
        if (o.size() == 0)
            return e.size();
  
        // If graph have atleast one 
        // even connected component
        if (e.size() != 0)
            ans += e.size();
  
        // For all the odd connected component.
        for (int i : o)
            ans += odd[i] / 2;
  
        return ans;
    }
  
    // Driver Code
    public static void main(String[] args) throws IOException
    {
        int n = 3, m = 2;
        int[] source = { 1, 2 };
        int[] destination = { 2, 3 };
  
        System.out.println(minEdge(n, m, source, 
                                   destination));
    }
}
  
// This code is contributed by
// sanjeev2552


Python3
# Python3 program to find minimum edge 
# required to make Euler Circuit
  
# Depth-First Search to find a 
# connected component 
def dfs(g, vis, odd, deg, comp, v):
    vis[v] = 1
  
    if (deg[v] % 2 == 1): 
        odd[comp] += 1
          
    for u in range(len(g[v])):
        if (vis[u] == 0):
            dfs(g, vis, odd, deg, comp, u)
  
# Return minimum edge required to
# make Euler Circuit 
def minEdge(n, m, s, d):
      
    # g : to store adjacency list 
    #      representation of graph. 
    # e : to store list of even degree vertices 
    # o : to store list of odd degree vertices 
    g = [[] for i in range(n + 1)]
    e = []
    o = []
  
    deg = [0] * (n + 1) # Degrees of vertices 
    vis = [0] * (n + 1) # To store visited in DFS 
    odd = [0] * (n + 1) # Number of odd nodes
                        # in components 
      
    for i in range(m):
        g[s[i]].append(d[i]) 
        g[d[i]].append(s[i]) 
        deg[s[i]] += 1
        deg[d[i]] += 1
  
    # 'ans' is result and 'comp' 
    # is component id 
    ans = 0
    comp = 0
    for i in range(1, n + 1):
        if (vis[i] == 0):
            comp += 1
            dfs(g, vis, odd, deg, comp, i) 
  
            # Checking if connected component 
            # is odd. 
            if (odd[comp] == 0): 
                e.append(comp) 
  
            # Checking if connected component 
            # is even. 
            else:
                o.append(comp)
  
    # If whole graph is a single connected 
    # component with even degree. 
    if (len(o) == 0 and len(e) == 1): 
        return 0
  
    # If all connected component is even 
    if (len(o) == 0): 
        return len(e) 
  
    # If graph have atleast one 
    # even connected component 
    if (len(e) != 0): 
        ans += len(e)
  
    # For all the odd connected component. 
    for i in range(len(o)):
        ans += odd[i] // 2
  
    return ans
  
# Driver Code
if __name__ == '__main__':
  
    n = 3
    m = 2
    source = [ 1, 2 ]
    destination = [ 2, 3]
  
    print(minEdge(n, m, source, destination))
  
# This code is contributed by PranchalK



输出:
1