/// <summary> /// Podział grafu na cykle. Zakładamy, że dostajemy graf nieskierowany i wszystkie wierzchołki grafu mają parzyste stopnie /// (nie trzeba sprawdzać poprawności danych). /// </summary> /// <param name="G">Badany graf</param> /// <returns>Tablica cykli; krawędzie każdego cyklu powinny być uporządkowane zgodnie z kolejnością na cyklu, zaczynając od dowolnej</returns> /// <remarks> /// Metoda powinna działać w czasie O(m) /// </remarks> public static Edge[][] cyclePartition(this Graph G) { Graph g = G.Clone(); int v = 0; Stark <int> vertices = new Stark <int>(); Stark <Edge> cycleL = new Stark <Edge>(); Stark <Edge> cycleLR = new Stark <Edge>(); List <Edge[]> cycles = new List <Edge[]>(); bool[] visited = new bool[G.VerticesCount]; bool found = false; int end = -1, first = -1; vertices.Put(-1); while (g.EdgesCount != 0) { found = g.DFSfc(v, v, ref end, ref first, ref vertices, ref visited, ref cycleL); if (!found) { v = (v + 1) % g.VerticesCount; while (vertices.Count() != 1) { visited[vertices.Get()] = false; } continue; } int ind = cycleL.Count() - 1; while (cycleL.Peek().From != first) { g.DelEdge(cycleL.Peek()); cycleLR.Put(cycleL.Get()); } g.DelEdge(cycleL.Peek()); cycleLR.Put(cycleL.Get()); while (vertices.Count() != 1) { visited[vertices.Get()] = false; } cycles.Add(cycleLR.ToArray()); v = end; //} } Edge[][] ccls = cycles.ToArray(); return(ccls); }
static bool DFSfc(this Graph g, int v, int w, ref int end, ref int first, ref Stark <int> vl, ref bool[] visited, ref Stark <Edge> cycleL) { int u; visited[w] = true; foreach (Edge e in g.OutEdges(w)) { u = e.To; if (u != vl.Peek()) { vl.Put(w); cycleL.Put(e); if (visited[u]) { end = w; first = u; return(true); } if (!visited[u] && DFSfc(g, v, u, ref end, ref first, ref vl, ref visited, ref cycleL)) { return(true); } vl.Get(); } } return(false); }