/// <summary> /// Raise the level of the edge, optionally inserting into higher level trees /// </summary> public void RaiseLevel() { // Update position in edge lists source.RemoveEdge(this); dest.RemoveEdge(this); level++; EdgeListUtility.InsertEdge(source.adjacent, this); EdgeListUtility.InsertEdge(dest.adjacent, this); // Update flags for s if (source.euler.Count <= level) { source.euler.Add(EulerVertex <DynamicNode <T> > .Create(source)); } var es = source.euler[level]; es.SetFlag(true); // Update flags for t if (dest.euler.Count <= level) { dest.euler.Add(EulerVertex <DynamicNode <T> > .Create(dest)); } var et = dest.euler[level]; et.SetFlag(true); // If the edge is already part of a spanning tree, relink them in the next level if (euler != null) { euler.Add(es.Link(et, this)); } }
/// <summary> /// Remove edge from adjacent list /// </summary> public void RemoveEdge(DynamicEdge <T> edge) { var adj = adjacent; int idx = EdgeListUtility.Index(adj, edge); adj.RemoveAt(idx); // Check if flag needs to be updated if (!((idx < adj.Count && adj[idx].level == edge.level) || (idx > 0 && adj[idx - 1].level == edge.level))) { euler[edge.level].SetFlag(false); } }
public DynamicEdge <T> Link(DynamicVertex <T> other, T value) { var e = new DynamicEdge <T>(value, KeyCounter, this, other); KeyCounter++; if (!euler[0].IsConnected(other.euler[0])) { e.LinkSpanningForests(); } euler[0].SetFlag(true); other.euler[0].SetFlag(true); EdgeListUtility.InsertEdge(adjacent, e); EdgeListUtility.InsertEdge(other.adjacent, e); return(e); }
/// <summary> /// Search over Tv for edge connecting to Tw /// </summary> private bool Visit(TreapNode <EulerNode <DynamicNode <T> > > node, int level) { if (node.flag) { var v = node.val.value as DynamicVertex <T>; var adj = v.adjacent; int ptr = EdgeListUtility.LevelIndex(adj, level); for (; ptr < adj.Count && adj[ptr].level == level; ptr++) { var e = adj[ptr]; var es = e.source; var et = e.dest; if (es.euler[level].IsConnected(et.euler[level])) { // Raise edge level if dest is in current tree e.RaiseLevel(); ptr--; } else { // Otherwise, connect trees and finish, because dest is in target tree e.LinkSpanningForests(); return(true); } } } if (node.left != null && node.left.flagAggregate) { if (Visit(node.left, level)) { return(true); } } if (node.right != null && node.right.flagAggregate) { if (Visit(node.right, level)) { return(true); } } return(false); }