public bool Possible() { Graph g = new Graph(N * 2, E, true); TarjanSCC scc = new TarjanSCC(g); for (int v = 0; v < N; v++) { if (scc.StronglyConnected(v << 1, (v << 1) ^ 1)) { return(false); } } return(true); }
// 参考解答 连通性 + 最小生成树性质 public static IList <IList <int> > FindCriticalAndPseudoCriticalEdges_1(int n, int[][] edges) { int length = edges.Length; var newEdges = edges.Select((item, index) => (X: item[0], Y: item[1], V: item[2], Index: index)) .OrderBy(item => item.V) .ToArray(); UnionFind unionFind = new UnionFind(n); IList <IList <int> > result = new List <IList <int> >(); for (int i = 0; i < 2; i++) { result.Add(new List <int>()); } int[] label = new int[length]; int index = 0; while (index < length) { int v = newEdges[index].V; int j = index; while (j < length && newEdges[j].V == v) { j++; } Dictionary <int, int> compToId = new Dictionary <int, int>(); int gn = 0; for (int k = index; k < j; k++) { int x = newEdges[k].X; int y = newEdges[k].Y; if (x != y) { if (!compToId.ContainsKey(x)) { compToId[x] = gn++; } if (!compToId.ContainsKey(y)) { compToId[y] = gn++; } } else { label[newEdges[k].Index] = -1; } } List <int>[] gm = new List <int> [gn]; List <int>[] gmid = new List <int> [gn]; for (int k = 0; k < gn; k++) { gm[k] = new List <int>(); gmid[k] = new List <int>(); } for (int k = index; k < j; k++) { int x = newEdges[k].X; int y = newEdges[k].Y; if (x == y) { continue; } int idX = compToId[x]; int idY = compToId[y]; gm[idX].Add(idY); gmid[idX].Add(newEdges[k].Index); gm[idY].Add(idX); gmid[idY].Add(newEdges[k].Index); } List <int> bridges = new TarjanSCC(gn, gm, gmid).CuttingEdge; foreach (int id in bridges) { result[0].Add(id); label[id] = 1; } for (int k = index; k < j; k++) { unionFind.Union(newEdges[k].X, newEdges[k].Y); } index = j; } for (int i = 0; i < length; i++) { if (label[i] == 0) { result[i].Add(i); } } return(result); }
public void Run() { Console.WriteLine("Choose file:"); // Prompt Console.WriteLine("1 - tinyDG.txt"); // Prompt Console.WriteLine("2 - mediumDG.txt"); // Prompt Console.WriteLine("or quit"); // Prompt var fileNumber = Console.ReadLine(); string fileName; switch (fileNumber) { case "1": fileName = "tinyDG.txt"; break; case "2": fileName = "mediumDG.txt"; break; case "quit": return; default: return; } var @in = new In($"Files\\Graphs\\{fileName}"); var lines = @in.ReadAllLines(); var lineIterator = 0; var v = 0; var e = 0; var edges = new List <EdgeD>(); foreach (var line in lines) { if (lineIterator == 0) { v = Convert.ToInt32(line); } if (lineIterator == 1) { e = Convert.ToInt32(line); } if (lineIterator > 1) { var lineSplitted = line.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); var ve = Convert.ToInt32(lineSplitted[0]); var we = Convert.ToInt32(lineSplitted[1]); var edge = new EdgeD(ve, we); edges.Add(edge); } lineIterator++; } var digraph = new Digraph(v, e, edges); Console.WriteLine(digraph); var scc = new TarjanSCC(digraph); // number of connected components var m = scc.Count(); Console.WriteLine($"{m} components"); // compute list of vertices in each strong component var components = new Core.Collections.Queue <Integer> [m]; for (var i = 0; i < m; i++) { components[i] = new Core.Collections.Queue <Integer>(); } for (var i = 0; i < digraph.V; i++) { components[scc.Id(i)].Enqueue(i); } // print results for (var i = 0; i < m; i++) { foreach (int j in components[i]) { Console.Write($"{j} "); } Console.WriteLine(); } Console.ReadLine(); }
public static void ShowCycles(int pos, Document document) { Dictionary <string, string> result = new Dictionary <string, string>(); // Check if initial file is a grammar. ParsingResults pd_parser = ParsingResultsFactory.Create(document) as ParsingResults; if (pd_parser == null) { throw new LanguageServerException("A grammar file is not selected. Please select one first."); } Transform.ExtractGrammarType egt = new Transform.ExtractGrammarType(); ParseTreeWalker.Default.Walk(egt, pd_parser.ParseTree); bool is_grammar = egt.Type == Transform.ExtractGrammarType.GrammarType.Parser || egt.Type == Transform.ExtractGrammarType.GrammarType.Combined || egt.Type == Transform.ExtractGrammarType.GrammarType.Lexer; if (!is_grammar) { throw new LanguageServerException("A grammar file is not selected. Please select one first."); } // Find all other grammars by walking dependencies (import, vocab, file names). HashSet <string> read_files = new HashSet <string> { document.FullPath }; Dictionary <Workspaces.Document, List <TerminalNodeImpl> > every_damn_literal = new Dictionary <Workspaces.Document, List <TerminalNodeImpl> >(); for (; ;) { int before_count = read_files.Count; foreach (string f in read_files) { List <string> additional = ParsingResults.InverseImports.Where( t => t.Value.Contains(f)).Select( t => t.Key).ToList(); read_files = read_files.Union(additional).ToHashSet(); } foreach (string f in read_files) { var additional = ParsingResults.InverseImports.Where( t => t.Key == f).Select( t => t.Value); foreach (var t in additional) { read_files = read_files.Union(t).ToHashSet(); } } int after_count = read_files.Count; if (after_count == before_count) { break; } } // Construct graph of symbol usage. Transform.TableOfRules table = new Transform.TableOfRules(pd_parser, document); table.ReadRules(); table.FindPartitions(); table.FindStartRules(); Digraph <string> graph = new Digraph <string>(); foreach (Transform.TableOfRules.Row r in table.rules) { if (!r.is_parser_rule) { continue; } graph.AddVertex(r.LHS); } foreach (Transform.TableOfRules.Row r in table.rules) { if (!r.is_parser_rule) { continue; } List <string> j = r.RHS; //j.Reverse(); foreach (string rhs in j) { Transform.TableOfRules.Row sym = table.rules.Where(t => t.LHS == rhs).FirstOrDefault(); if (!sym.is_parser_rule) { continue; } DirectedEdge <string> e = new DirectedEdge <string>(r.LHS, rhs); graph.AddEdge(e); } } List <string> starts = new List <string>(); List <string> parser_lhs_rules = new List <string>(); foreach (Transform.TableOfRules.Row r in table.rules) { if (r.is_parser_rule) { parser_lhs_rules.Add(r.LHS); if (r.is_start) { starts.Add(r.LHS); } } } IParseTree rule = null; IParseTree it = pd_parser.AllNodes.Where(n => { if (!(n is ANTLRv4Parser.ParserRuleSpecContext || n is ANTLRv4Parser.LexerRuleSpecContext)) { return(false); } Interval source_interval = n.SourceInterval; int a = source_interval.a; int b = source_interval.b; IToken ta = pd_parser.TokStream.Get(a); IToken tb = pd_parser.TokStream.Get(b); var start = ta.StartIndex; var stop = tb.StopIndex + 1; return(start <= pos && pos < stop); }).FirstOrDefault(); rule = it; var k = (ANTLRv4Parser.ParserRuleSpecContext)rule; var tarjan = new TarjanSCC <string, DirectedEdge <string> >(graph); List <string> ordered = new List <string>(); var sccs = tarjan.Compute(); StringBuilder sb = new StringBuilder(); sb.AppendLine("Cycles in " + document.FullPath); var done = new List <IEnumerable <string> >(); foreach (var scc in sccs) { if (scc.Value.Count() <= 1) { continue; } if (!done.Contains(scc.Value)) { foreach (var s in scc.Value) { sb.Append(" "); sb.Append(s); } sb.AppendLine(); sb.AppendLine(); done.Add(scc.Value); } } //var scc = sccs[k.RULE_REF().ToString()]; //foreach (var v in scc) //{ // ordered.Add(v); //} }