Example #1
0
 //O(V+E)
 void RunDFSForSCC(int node)
 {
     _nodeDict[node] = new NodeDiscAndLow {
         DiscoveryTime = _time, EarliestAccessibleNode = _time
     };
     _time++;
     _inStack.Add(node);
     _myStack.Push(node);
     foreach (var nbor in _adj[node])
     {
         if (_nodeDict.ContainsKey(nbor)) //Already processed
         {
             if (_inStack.Contains(nbor)) //BackEdge, ignore cross edges
             {                            //For BE u->v, EAN (Earliest Accessible Node) is Min(u.EAN,v.DiscoveryTime)
                 _nodeDict[node].EarliestAccessibleNode =
                     Math.Min(_nodeDict[node].EarliestAccessibleNode, _nodeDict[nbor].DiscoveryTime);
             }
         }
         else
         {
             RunDFSForSCC(nbor);
             //Update EarliestAccessibleNode
             _nodeDict[node].EarliestAccessibleNode =
                 Math.Min(_nodeDict[node].EarliestAccessibleNode, _nodeDict[nbor].EarliestAccessibleNode);
         }
     }
     //When exiting check if this is the start of a strongly connected component
     if (_nodeDict[node].EarliestAccessibleNode == _nodeDict[node].DiscoveryTime) //Is a strongly connected component
     {
         var component = new List <int>();
         PopFromStack(_nodeDict[node].EarliestAccessibleNode, component);
         _components.Add(component);
     }
 }
Example #2
0
        //O(V+E)
        void RunDFSForBridges(int node, int parent)
        {
            _nodeDict[node] = new NodeDiscAndLow {
                DiscoveryTime = _time, EarliestAccessibleNode = _time
            };
            _time++;
            if (parent != -1)
            {
                _parents.Add(node, parent);
            }
            var childrenCount = 0; //Track children count

            foreach (var nbor in _adj[node])
            {
                childrenCount++;
                if (nbor == parent)
                {
                    continue;
                }
                if (_nodeDict.ContainsKey(nbor))
                {
                    _nodeDict[node].EarliestAccessibleNode =
                        Math.Min(_nodeDict[node].EarliestAccessibleNode, _nodeDict[nbor].DiscoveryTime);
                }
                else
                {
                    RunDFSForBridges(nbor, node);
                    _nodeDict[node].EarliestAccessibleNode =
                        Math.Min(_nodeDict[node].EarliestAccessibleNode, _nodeDict[nbor].EarliestAccessibleNode);

                    if (_nodeDict[nbor].EarliestAccessibleNode > _nodeDict[node].DiscoveryTime)//Bridge
                    {
                        _bridges.Add(new SharedClasses.Edge {
                            FromNode = node, ToNode = nbor
                        });
                    }

                    if (parent == -1 && childrenCount > 1) //If this is the root, and it has 2 or more children, it must be an articulation point.
                    {
                        _artPoints.Add(node);
                    }
                    else if (parent != -1 && _nodeDict[nbor].EarliestAccessibleNode >= _nodeDict[node].DiscoveryTime)//IF not root, this is an Articulation point
                    {
                        _artPoints.Add(node);
                    }
                }
            }
        }