给定具有V个节点(例如,从1到V的编号)和E边的无向图,任务是检查该图是否为欧拉图,如果是,则将其转换为有向欧拉电路。
A Directed Euler Circuit is a directed graph such that if you start traversing the graph from any node and travel through each edge exactly once you will end up on the starting node.
注意:在遍历欧拉电路时,每个边沿仅精确遍历一次。如果需要,可以多次遍历一个节点,但是不能多次遍历一条边。
例子:
Input:
Output:
1 2
2 5
5 1
2 4
4 3
3 2
Explanation:
The Directed Euler Circuit for the given undirected graph will be:
方法:
- 首先,我们需要确保给定的无向图是否为欧拉图。如果无向图不是欧拉图,则无法将其转换为有向欧拉图。
- 为了检查它,我们只需要计算每个节点的度数即可。如果所有节点的度数为偶数且不等于0,则该图为欧拉式。
- 我们将使用“深度优先搜索遍历”来分配方向。
- 在遍历时,我们将设置从父对象到子对象的边的方向。我们将维护一个地图,以确保仅对边进行一次遍历。
下面是上述算法的实现:
C++
// C++ program to Convert an
// Undirected Graph to a
// Directed Euler Circuit
#include
using namespace std;
vector g[100];
// Array to store degree
// of nodes.
int deg[100] = { 0 };
// Map to keep a track of
// visited edges
map, int> m1;
// Vector to store the edge
// pairs
vector > v;
// Function to add Edge
void addEdge(int u, int v)
{
deg[u]++;
deg[v]++;
g[u].push_back(v);
g[v].push_back(u);
}
// Function to check if graph
// is Eulerian or not
bool CheckEulerian(int n)
{
int check = 0;
for (int i = 1; i <= n; i++) {
// Checking if odd degree
// or zero degree nodes
// are present
if (deg[i] % 2 || deg[i] == 0) {
check = 1;
break;
}
}
// If any degree is odd or
// any vertex has degree 0
if (check) {
return false;
}
return true;
}
// DFS Function to assign the direction
void DirectedEuler(int node,
vector g[])
{
for (auto i = g[node].begin();
i != g[node].end(); i++) {
// Checking if edge is already
// visited
if (m1[make_pair(node, *i)]
|| m1[make_pair(*i, node)])
continue;
m1[make_pair(node, *i)]++;
// Storing the edge
v.push_back(make_pair(node, *i));
DirectedEuler(*i, g);
}
}
// Function prints the convert
// Directed graph
void ConvertDirectedEuler(int n,
int e)
{
if (!CheckEulerian(n)) {
cout << "NOT POSSIBLE"
<< endl;
return;
}
DirectedEuler(1, g);
// Printing directed edges
for (auto i = v.begin();
i != v.end(); i++) {
cout << (*i).first
<< " "
<< (*i).second
<< endl;
}
}
// Driver code
int main()
{
int N = 5;
int E = 6;
addEdge(1, 2);
addEdge(1, 5);
addEdge(5, 2);
addEdge(2, 4);
addEdge(2, 3);
addEdge(4, 3);
ConvertDirectedEuler(N, E);
}
Java
// Java program to Convert an
// Undirected Graph to a
// Directed Euler Circuit
import java.io.*;
import java.lang.*;
import java.util.*;
class GFG{
// Pair class to store Key in map
static class Pair
{
int first;
int second;
Pair(int first, int second)
{
this.first = first;
this.second = second;
}
@Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + first;
result = prime * result + second;
return result;
}
@Override
public boolean equals(Object obj)
{
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Pair other = (Pair) obj;
if (first != other.first)
return false;
if (second != other.second)
return false;
return true;
}
}
// To store graph
static ArrayList g[];
// Array to store degree of nodes.
static int deg[];
// Vector to store the edge pairs
static ArrayList v;
// Map to keep a track of
// visited edges
static HashMap m1;
@SuppressWarnings("unchecked")
static void initialize()
{
g = new ArrayList[100];
for(int i = 0; i < 100; i++)
g[i] = new ArrayList<>();
deg = new int[100];
v = new ArrayList<>();
m1 = new HashMap<>();
}
// Function to add Edge
static void addEdge(int u, int v)
{
deg[u]++;
deg[v]++;
g[u].add(v);
g[v].add(u);
}
// Function to check if graph
// is Eulerian or not
static boolean CheckEulerian(int n)
{
int check = 0;
for(int i = 1; i <= n; i++)
{
// Checking if odd degree
// or zero degree nodes
// are present
if (deg[i] % 2 == 1 || deg[i] == 0)
{
check = 1;
break;
}
}
// If any degree is odd or
// any vertex has degree 0
if (check == 1)
{
return false;
}
return true;
}
// DFS Function to assign the direction
static void DirectedEuler(int node,
ArrayList g[])
{
for(int i : g[node])
{
// Checking if edge is already
// visited
if (m1.containsKey(new Pair(node, i)) ||
m1.containsKey(new Pair(i, node)))
continue;
m1.put(new Pair(node, i), 1);
// Storing the edge
v.add(new Pair(node, i));
DirectedEuler(i, g);
}
}
// Function prints the convert
// Directed graph
static void ConvertDirectedEuler(int n, int e)
{
if (!CheckEulerian(n))
{
System.out.println("NOT POSSIBLE");
return;
}
DirectedEuler(1, g);
// Printing directed edges
for(Pair p : v)
{
System.out.println(p.first + " " + p.second);
}
}
// Driver Code
public static void main(String[] args)
{
int N = 5;
int E = 6;
// To initialize
initialize();
addEdge(1, 2);
addEdge(1, 5);
addEdge(5, 2);
addEdge(2, 4);
addEdge(2, 3);
addEdge(4, 3);
ConvertDirectedEuler(N, E);
}
}
// This code is contributed by Kingash
Python3
# Python program to Convert an
# Undirected Graph to a
# Directed Euler Circuit
from typing import List
g = [[] for _ in range(100)]
# Array to store degree
# of nodes.
deg = [0 for _ in range(100)]
# Map to keep a track of
# visited edges
m1 = dict()
# Vector to store the edge
# pairs
v = []
# Function to add Edge
def addEdge(u: int, v: int) -> None:
global deg, g
deg[u] += 1
deg[v] += 1
g[u].append(v)
g[v].append(u)
# Function to check if graph
# is Eulerian or not
def CheckEulerian(n: int) -> bool:
check = 0
for i in range(1, n + 1):
# Checking if odd degree
# or zero degree nodes
# are present
if (deg[i] % 2 or deg[i] == 0):
check = 1
break
# If any degree is odd or
# any vertex has degree 0
if (check):
return False
return True
# DFS Function to assign the direction
def DirectedEuler(node: int, g: List[List[int]]) -> None:
for i in g[node]:
# Checking if edge is already
# visited
if ((node, i) in m1 or (i, node) in m1):
continue
if (node, i) not in m1:
m1[(node, i)] = 0
m1[(node, i)] += 1
# Storing the edge
v.append((node, i))
DirectedEuler(i, g)
# Function prints the convert
# Directed graph
def ConvertDirectedEuler(n: int, e: int) -> None:
if (not CheckEulerian(n)):
print("NOT POSSIBLE")
return
DirectedEuler(1, g)
# Printing directed edges
for i in v:
print("{} {}".format(i[0], i[1]))
# Driver code
if __name__ == "__main__":
N = 5
E = 6
addEdge(1, 2)
addEdge(1, 5)
addEdge(5, 2)
addEdge(2, 4)
addEdge(2, 3)
addEdge(4, 3)
ConvertDirectedEuler(N, E)
# This code is contributed by sanjeev2552
输出:
1 2
2 5
5 1
2 4
4 3
3 2
时间复杂度: O((V + E)* log(E))
空间复杂度: O(max(V,E))