-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathEdgeDisjointPath.cs
More file actions
79 lines (64 loc) · 2.41 KB
/
EdgeDisjointPath.cs
File metadata and controls
79 lines (64 loc) · 2.41 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
using System.Collections.Generic;
namespace AlgorithmsAndDataStructures.Algorithms.Graph.MaximumFlow;
public class EdgeDisjointPath
{
#pragma warning disable CA1822 // Mark members as static
public int GetEdgeDisjointPathCount(int[][] graph)
#pragma warning restore CA1822 // Mark members as static
{
if (graph is null) return default;
var residualGraph = new int[graph.Length][];
for (var i = 0; i < graph.Length; i++)
{
residualGraph[i] = new int[graph.Length];
for (var j = 0; j < residualGraph[i].Length; j++) residualGraph[i][j] = graph[i][j];
}
const int source = 0;
var sink = graph.Length - 1;
bool hasPath;
var edgeDisjointPathCount = 0;
do
{
var path = GetPath(residualGraph, source, sink);
hasPath = path != null;
if (hasPath)
{
// We don't need to calculate delta for this kind of problem since all edges has max 1 capacity.
var delta = 1;
var currentVertex = sink;
var parent = path[sink];
edgeDisjointPathCount += 1;
while (parent >= 0)
{
residualGraph[parent][currentVertex] = residualGraph[parent][currentVertex] - delta;
residualGraph[currentVertex][parent] = residualGraph[currentVertex][parent] + delta;
currentVertex = parent;
parent = path[currentVertex];
}
}
} while (hasPath);
return edgeDisjointPathCount;
}
private static int[] GetPath(IReadOnlyList<int[]> residualGraph, int source, int sink)
{
var queue = new Queue<int>();
var visited = new bool[residualGraph.Count];
var path = new int[residualGraph.Count];
queue.Enqueue(source);
visited[source] = true;
path[source] = -1;
while (queue.Count > 0)
{
var currentVertex = queue.Dequeue();
for (var i = 0; i < residualGraph[currentVertex].Length; i++)
if (!visited[i] && residualGraph[currentVertex][i] > 0)
{
path[i] = currentVertex;
visited[i] = true;
queue.Enqueue(i);
if (i == sink) return path;
}
}
return null;
}
}