You are on page 1of 8

Thuật toán fleury sử dụng stack

using System;

using System.Collections.Generic;

class Program

const int MAXN = 1001;

static int[,] adj = new int[MAXN, MAXN];

static int[] deg = new int[MAXN];

static int[] number = new int[MAXN];

static void enter(ref int n)

n = int.Parse(Console.ReadLine());

string[] tokens;

while ((tokens = Console.ReadLine().Split(' ')).Length == 3)

int u = int.Parse(tokens[0]);

int v = int.Parse(tokens[1]);

int k = int.Parse(tokens[2]);

adj[u, v] = adj[v, u] = k;

deg[u] += k;

deg[v] += k;

static void dfs(int n, int u, int cnt_comps)

number[u] = cnt_comps;
for (int v = 1; v <= n; ++v)

if (number[v] == 0 && adj[u, v] > 0)

dfs(n, v, cnt_comps);

static bool check_euler_graph(int n)

int cnt_comps = 0;

for (int u = 1; u <= n; ++u)

if (number[u] == 0)

++cnt_comps;

dfs(n, u, cnt_comps);

if (cnt_comps > 1)

return false;

for (int u = 1; u <= n; ++u)

if (deg[u] % 2 == 1)

return false;

return true;

static void fleury_stack(int n)

if (!check_euler_graph(n))

Console.Write(0);

return;
}

Stack<int> vertexes = new Stack<int>();

List<int> circuit = new List<int>();

vertexes.Push(1);

while (vertexes.Count > 0)

int u = vertexes.Peek();

for (int v = 1; v <= n; ++v)

if (adj[u, v] > 0)

--adj[u, v];

--adj[v, u];

vertexes.Push(v);

break;

if (u == vertexes.Peek())

circuit.Add(u);

vertexes.Pop();

for (int i = circuit.Count - 1; i >= 0; --i)

Console.Write(circuit[i] + " ");

static void Main()


{

int n = 0;

enter(ref n);

fleury_stack(n);

}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Thuật_toán_fleury
{
class Program
{
static void Main(string[] args)
{
// Tạo đồ thị của bài toán Königsberg
Console.OutputEncoding = Encoding.UTF8;
int n = 4; // số đỉnh
int[,] graph = new int[,]
{
{0, 1, 1, 1},
{1, 0, 1, 1},
{1, 1, 0, 1},
{1, 1, 1, 0}
};
// Gọi hàm tìm đường đi Euler và in ra kết quả
List<int> path = FleuryAlgorithm(graph);
if (path != null)
{
Console.Write("Tìm thấy đường đi Euler: ");
foreach (int vertex in path)
{
Console.Write(vertex + " ");
}
}
else
{
Console.WriteLine("Không tìm thấy đường đi Euler trên đồ thị này.");
}
Console.ReadKey();
}

// Hàm tìm đường đi Euler trên đồ thị không hướng


static List<int> FleuryAlgorithm(int[,] graph)
{
int n = graph.GetLength(0); // số đỉnh
int m = CountEdges(graph); // số cạnh
int startVertex = FindStartVertex(graph); // tìm đỉnh xuất phát
if (startVertex == -1)
{
return null; // không có đường đi Euler
}
List<int> path = new List<int>(); // đường đi
path.Add(startVertex); // thêm đỉnh xuất phát vào đường đi
int currentVertex = startVertex;
while (path.Count < m + 1)
{
// Tìm đỉnh kề của currentVertex không thuộc đường đi
int nextVertex = -1;
for (int i = 0; i < n; i++)
{
if (graph[currentVertex, i] != 0 && !path.Contains(i))
{
nextVertex = i;
break;
}
}
if (nextVertex == -1)
{
return null; // không có đường đi Euler
}
// Kiểm tra nếu nextVertex là đỉnh cầu
bool isBridge = IsBridge(graph, currentVertex, nextVertex);
if (isBridge)
{
// Nếu nextVertex là đỉnh cầu, thêm nó vào đường đi và xóa cạnh
giữa currentVertex và nextVertex
path.Add(nextVertex);
graph[currentVertex, nextVertex] = 0;
graph[nextVertex, currentVertex] = 0;
}
else
{
// Nếu nextVertex không là đỉnh cầu, chỉ thêm nó vào đường đi
path.Add(nextVertex);
}
currentVertex = nextVertex;
}
return path;
}

// Hàm đếm số cạnh của đồ thị


static int CountEdges(int[,] graph)
{
int n = graph.GetLength(0);
int count = 0;
for (int i = 0; i < n; i++)
{
for (int j = i + 1; j < n; j++)
{
if (graph[i, j] != 0)
{
count++;
}
}
}
return count;
}

// Hàm tìm đỉnh xuất phát để bắt đầu tìm đường đi Euler
static int FindStartVertex(int[,] graph)
{
int n = graph.GetLength(0);
int[] degrees = new int[n];
// Tính bậc của các đỉnh
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
if (graph[i, j] != 0)
{
degrees[i]++;
}
}
}
// Tìm đỉnh có bậc lẻ
int startVertex = -1;
for (int i = 0; i < n; i++)
{
if (degrees[i] % 2 != 0)
{
startVertex = i;
break;
}
}
return startVertex;
}

// Hàm kiểm tra xem cạnh (u, v) có phải là đỉnh cầu trên đồ thị không hướng
static bool IsBridge(int[,] graph, int u, int v)
{
int n = graph.GetLength(0);
bool[] visited = new bool[n];
visited[u] = true;
int count1 = DFSCount(graph, visited, u);
visited[u] = false;
visited[v] = true;
int count2 = DFSCount(graph, visited, v);
visited[v] = false;
// Kiểm tra xem việc xóa cạnh (u, v) có làm tăng số thành phần liên thông
hay không
graph[u, v] = 0;
graph[v, u] = 0;
visited[u] = true;
int newCount1 = DFSCount(graph, visited, u);
visited[u] = false;
visited[v] = true;
int newCount2 = DFSCount(graph, visited, v);
visited[v] = false;
graph[u, v] = 1;
graph[v, u] = 1;
return (newCount1 == count1 - 1 && newCount2 == count2 - 1);
}

// Hàm đếm số đỉnh được duyệt khi duyệt đồ thị từ đỉnh start bằng DFS
static int DFSCount(int[,] graph, bool[] visited, int start)
{
int n = graph.GetLength(0);
int count = 1;
for (int i = 0; i < n; i++)
{
if (graph[start, i] != 0 && !visited[i])
{
visited[i] = true;
count += DFSCount(graph, visited, i);
}
}
return count;
}
}
}

You might also like