26 using System.Collections.Generic;
55 public int Count {
get;
private set; }
58 public List<HashSet<Node>>
Components {
get;
private set; }
60 private class MyDfs :
Dfs
64 protected override void Start(out Direction direction)
66 direction = Direction.Undirected;
69 protected override bool NodeEnter(Node node, Arc arc)
71 if (arc == Arc.Invalid)
74 if (Parent.Components != null) Parent.Components.Add(
new HashSet<Node> { node });
76 else if (Parent.Components != null) Parent.Components[Parent.Count - 1].Add(node);
85 if (0 != (flags &
Flags.CreateComponents))
Components =
new List<HashSet<Node>>();
86 new MyDfs { Parent =
this }.Run(graph);
122 public HashSet<Node>
RedNodes {
get;
private set; }
128 private class MyDfs :
Dfs
131 private HashSet<Node> redNodes;
133 protected override void Start(out Direction direction)
135 direction = Direction.Undirected;
136 Parent.Bipartite =
true;
137 redNodes = Parent.RedNodes ??
new HashSet<Node>();
140 protected override bool NodeEnter(Node node, Arc arc)
142 if ((Level & 1) == 0)
145 if (Parent.BlueNodes != null) Parent.BlueNodes.Add(node);
149 protected override bool BackArc(Node node, Arc arc)
152 if (redNodes.Contains(node) == redNodes.Contains(other))
154 Parent.Bipartite =
false;
155 if (Parent.RedNodes != null) Parent.RedNodes.Clear();
156 if (Parent.BlueNodes != null) Parent.BlueNodes.Clear();
166 if (0 != (flags &
Flags.CreateRedNodes))
RedNodes =
new HashSet<Node>();
167 if (0 != (flags &
Flags.CreateBlueNodes))
BlueNodes =
new HashSet<Node>();
168 new MyDfs { Parent =
this }.Run(graph);
191 public List<Node>
Order {
get;
private set; }
193 private class MyDfs :
Dfs
196 private HashSet<Node> exited;
198 protected override void Start(out Direction direction)
200 direction = Direction.Forward;
201 Parent.Acyclic =
true;
202 exited =
new HashSet<Node>();
205 protected override bool NodeEnter(Node node, Arc arc)
209 Parent.Acyclic =
false;
215 protected override bool NodeExit(Node node, Arc arc)
217 if (Parent.Order != null) Parent.Order.Add(node);
222 protected override bool BackArc(Node node, Arc arc)
225 if (!exited.Contains(other))
227 Parent.Acyclic =
false;
233 protected override void StopSearch()
235 if (Parent.Order != null)
237 if (Parent.Acyclic) Parent.Order.Reverse();
238 else Parent.Order.Clear();
246 if (0 != (flags &
Flags.CreateOrder))
Order =
new List<Node>();
247 new MyDfs { Parent =
this }.Run(graph);
266 public int Count {
get;
private set; }
272 private class ForwardDfs :
Dfs
274 public List<Node> ReverseExitOrder;
276 protected override void Start(out Direction direction)
278 direction = Direction.Forward;
279 ReverseExitOrder =
new List<Node>();
282 protected override bool NodeExit(Node node, Arc arc)
284 ReverseExitOrder.Add(node);
288 protected override void StopSearch()
290 ReverseExitOrder.Reverse();
294 private class BackwardDfs : Dfs
298 protected override void Start(out Direction direction)
303 protected override bool NodeEnter(Node node, Arc arc)
305 if (arc ==
Arc.Invalid)
308 if (Parent.Components != null) Parent.Components.Add(
new HashSet<Node> { node });
310 else if (Parent.Components != null) Parent.Components[Parent.Components.Count - 1].Add(node);
319 if (0 != (flags &
Flags.CreateComponents))
Components =
new List<HashSet<Node>>();
321 var forwardDfs =
new ForwardDfs();
322 forwardDfs.Run(graph);
323 var backwardDfs =
new BackwardDfs { Parent =
this };
324 backwardDfs.Run(graph, forwardDfs.ReverseExitOrder);
329 internal class LowpointDfs : Dfs
331 protected Dictionary<Node, int> level;
332 protected Dictionary<Node, int> lowpoint;
334 private void UpdateLowpoint(Node node,
int newLowpoint)
336 if (lowpoint[node] > newLowpoint) lowpoint[node] = newLowpoint;
339 protected override void Start(out Direction direction)
342 level =
new Dictionary<Node, int>();
343 lowpoint =
new Dictionary<Node, int>();
346 protected override bool NodeEnter(Node node, Arc arc)
349 lowpoint[node] =
Level;
353 protected override bool NodeExit(Node node, Arc arc)
355 if (arc !=
Arc.Invalid)
358 UpdateLowpoint(parent, lowpoint[node]);
363 protected override bool BackArc(Node node, Arc arc)
366 UpdateLowpoint(node, level[other]);
370 protected override void StopSearch()
377 internal class BridgeDfs : LowpointDfs
379 public int ComponentCount;
380 public HashSet<Arc> Bridges;
382 protected override void Start(out Direction direction)
384 base.Start(out direction);
386 Bridges =
new HashSet<Arc>();
389 protected override bool NodeExit(Node node, Arc arc)
391 if (arc ==
Arc.Invalid) ComponentCount++;
394 if (lowpoint[node] == Level)
401 return base.NodeExit(node, arc);
421 public int Count {
get;
private set; }
427 public HashSet<Arc>
Bridges {
get;
private set; }
432 var dfs =
new BridgeDfs();
435 Count = dfs.ComponentCount;
436 if (0 != (flags &
Flags.CreateBridges))
Bridges = dfs.Bridges;
437 if (0 != (flags &
Flags.CreateComponents))
440 foreach (var arc
in dfs.Bridges) withoutBridges.Enable(arc,
false);
463 public int Count {
get;
private set; }
473 private class BlockDfs : LowpointDfs
476 private Stack<Node> blockStack;
477 private bool oneNodeComponent;
479 protected override void Start(out Direction direction)
481 base.Start(out direction);
482 if (Parent.Components != null) blockStack =
new Stack<Node>();
485 protected override bool NodeEnter(Node node, Arc arc)
487 if (!base.NodeEnter(node, arc))
return false;
489 if (Parent.Cutvertices != null && arc == Arc.Invalid) Parent.
Cutvertices[node] = -1;
490 if (Parent.Components != null) blockStack.Push(node);
491 oneNodeComponent = (arc == Arc.Invalid);
495 protected override bool NodeExit(Node node, Arc arc)
497 if (arc ==
Arc.Invalid)
499 if (oneNodeComponent)
502 if (Parent.Components != null) Parent.Components.Add(
new HashSet<Node> { node });
505 if (Parent.Cutvertices != null && Parent.Cutvertices[node] == 0) Parent.Cutvertices.Remove(node);
506 if (Parent.Components != null) blockStack.Clear();
512 if (lowpoint[node] >= Level - 1)
514 if (Parent.Cutvertices != null)
517 Parent.Cutvertices[parent] = (Parent.Cutvertices.TryGetValue(parent, out degree) ? degree : 0) + 1;
521 if (Parent.Components != null)
523 HashSet<Node> block =
new HashSet<Node>();
526 Node n = blockStack.Pop();
528 if (n == node)
break;
531 Parent.Components.Add(block);
536 return base.NodeExit(node, arc);
543 if (0 != (flags &
Flags.CreateComponents))
Components =
new List<HashSet<Node>>();
544 if (0 != (flags &
Flags.CreateCutvertices))
Cutvertices =
new Dictionary<Node, int>();
545 new BlockDfs { Parent =
this }.Run(graph);
552 private class PathDfs :
Dfs
555 public Direction PathDirection;
556 public Func<Node, bool> IsTarget;
559 public Node StartNode;
560 public List<Arc>
Path;
563 protected override void Start(out Direction direction)
565 direction = PathDirection;
568 Path =
new List<Arc>();
572 protected override bool NodeEnter(
Node node,
Arc arc)
587 protected override bool NodeExit(
Node node,
Arc arc)
603 var dfs =
new PathDfs() { PathDirection = direction, IsTarget = target };
604 dfs.Run(graph, source);
607 var result =
new Path(graph);
608 result.Begin(dfs.StartNode);
609 foreach (var arc
in dfs.Path) result.AddLast(arc);
617 return FindPath(graph,
new Node[] { source }, x => x == target, direction);