public void RerootingTestABC160ExampleF() { var inputs = @"8 1 2 2 3 3 4 3 5 3 6 6 7 6 8".Split(Environment.NewLine); var n = int.Parse(inputs[0]); var graph = new BasicGraph(n); foreach (var input in inputs.Skip(1).Select(s => s.Split(' ').Select(s => int.Parse(s) - 1).ToArray())) { graph.AddEdge(input[0], input[1]); graph.AddEdge(input[1], input[0]); } var rerooting = new Rerooting <BasicEdge, DPState>(graph); var result = rerooting.Solve().Select(r => r.Count.Value); var expected = new int[] { 40, 280, 840, 120, 120, 504, 72, 72 }; Assert.Equal(expected, result); }
public override void Solve(IOManager io) { var n = io.ReadInt(); var tree = new BasicGraph(n); for (int i = 0; i < n - 1; i++) { var u = io.ReadInt(); var v = io.ReadInt(); u--; v--; tree.AddEdge(u, v); tree.AddEdge(v, u); } var lca = new LowestCommonAncester(tree); var queries = io.ReadInt(); for (int q = 0; q < queries; q++) { var a = io.ReadInt() - 1; var b = io.ReadInt() - 1; io.WriteLine(lca.Depths[a] + lca.Depths[b] - 2 * lca.Depths[lca.GetLcaNode(a, b)] + 1); } }
public override IEnumerable <object> Solve(TextReader inputStream) { var nodeCount = inputStream.ReadInt(); tree = new BasicGraph(nodeCount); counts = new int[nodeCount]; results = new int[nodeCount]; for (int i = 0; i < nodeCount - 1; i++) { var(a, b) = inputStream.ReadValue <int, int>(); a--; b--; counts[a]++; counts[b]++; tree.AddEdge(new BasicEdge(a, b)); tree.AddEdge(new BasicEdge(b, a)); } points = new Queue <int>(inputStream.ReadIntArray().OrderBy(i => i)); var total = points.Take(points.Count - 1).Sum(); Bfs(); yield return(total); yield return(results.Join(' ')); }
public override IEnumerable <object> Solve(TextReader inputStream) { Modular.InitializeCombinationTable(); var nodesCount = inputStream.ReadInt(); graph = new BasicGraph(nodesCount); for (int i = 0; i < nodesCount - 1; i++) { var(a, b) = inputStream.ReadValue <int, int>(); a--; b--; graph.AddEdge(new BasicEdge(a, b)); graph.AddEdge(new BasicEdge(b, a)); } dpStates = new DPState[nodesCount]; for (int i = 0; i < dpStates.Length; i++) { dpStates[i] = new DPState(new Modular(1), 0); } var rerooting = new Rerooting <BasicNode, BasicEdge, DPState>(graph); var results = rerooting.Solve().Select(r => r.Count.Value); foreach (var result in results) { yield return(result); } }
public override IEnumerable <object> Solve(TextReader inputStream) { var n = inputStream.ReadInt(); maxValues = Enumerable.Repeat(int.MaxValue, n).ToArray(); minValues = Enumerable.Repeat(int.MinValue, n).ToArray(); graph = new BasicGraph(n); for (int i = 0; i < n - 1; i++) { var(a, b) = inputStream.ReadValue <int, int>(); a--; b--; graph.AddEdge(new BasicEdge(a, b)); graph.AddEdge(new BasicEdge(b, a)); } var starts = new List <int>(); var k = inputStream.ReadInt(); for (int i = 0; i < k; i++) { var(v, p) = inputStream.ReadValue <int, int>(); v--; maxValues[v] = p; minValues[v] = p; starts.Add(v); } if (!CheckEvenOdd(starts[0], -1, minValues[starts[0]])) { yield return("No"); yield break; } //Shuffle(starts); foreach (var start in starts) { Dfs(start, -1, maxValues[start] + 1, minValues[start] - 1); } for (int i = 0; i < maxValues.Length; i++) { if (maxValues[i] < minValues[i]) { yield return("No"); yield break; } } yield return("Yes"); foreach (var value in minValues) { yield return(value); } }
public override IEnumerable <object> Solve(TextReader inputStream) { var(nodeCount, takahashiStart, aokiStart) = inputStream.ReadValue <int, int, int>(); takahashiStart--; aokiStart--; var tree = new BasicGraph(nodeCount); for (int i = 0; i < nodeCount - 1; i++) { var(a, b) = inputStream.ReadValue <int, int>(); a--; b--; tree.AddEdge(new BasicEdge(a, b)); tree.AddEdge(new BasicEdge(b, a)); } var takahashiDistances = GetDistances(takahashiStart); var aokiDistances = GetDistances(aokiStart); var result = 0; for (int i = 0; i < nodeCount; i++) { if (takahashiDistances[i] < aokiDistances[i]) { result = Math.Max(result, aokiDistances[i]); } } yield return(result - 1); int[] GetDistances(int startNode) { const int Inf = 1 << 28; var todo = new Queue <int>(); var distances = Enumerable.Repeat(Inf, nodeCount).ToArray(); todo.Enqueue(startNode); distances[startNode] = 0; while (todo.Count > 0) { var current = todo.Dequeue(); foreach (var edge in tree[current]) { var next = edge.To.Index; if (distances[next] == Inf) { distances[next] = distances[current] + 1; todo.Enqueue(next); } } } return(distances); } }
public override IEnumerable <object> Solve(TextReader inputStream) { const int A = 0; const int B = 1; var(nodeCount, edgeCount) = inputStream.ReadValue <int, int>(); var s = inputStream.ReadLine().Select(c => c == 'A' ? A : B).ToArray(); var graph = new BasicGraph(nodeCount); var adjacents = new int[nodeCount, B + 1]; for (int i = 0; i < edgeCount; i++) { var(a, b) = inputStream.ReadValue <int, int>(); a--; b--; adjacents[a, s[b]]++; adjacents[b, s[a]]++; graph.AddEdge(new BasicEdge(a, b)); graph.AddEdge(new BasicEdge(b, a)); } var queue = new Queue <int>(); var erased = new bool[nodeCount]; for (int i = 0; i < nodeCount; i++) { if (adjacents[i, A] == 0 || adjacents[i, B] == 0) { queue.Enqueue(i); erased[i] = true; } } while (queue.Count > 0) { var current = queue.Dequeue(); foreach (var edge in graph[current]) { var next = edge.To.Index; if (!erased[next]) { adjacents[next, s[current]]--; if (adjacents[next, A] == 0 || adjacents[next, B] == 0) { erased[next] = true; queue.Enqueue(next); } } } } yield return(erased.Any(b => !b) ? "Yes" : "No"); }
public override IEnumerable <object> Solve(TextReader inputStream) { var(nodeCount, edgeCount) = inputStream.ReadValue <int, int>(); if (nodeCount - 1 == edgeCount) { yield return(0); yield break; } var graph = new BasicGraph(nodeCount); for (int i = 0; i < edgeCount; i++) { var(x, y) = inputStream.ReadValue <int, int>(); graph.AddEdge(new BasicEdge(x, y)); graph.AddEdge(new BasicEdge(y, x)); } var groups = Enumerable.Repeat(-1, nodeCount).ToArray(); void Dfs(int current, int parent, int groupNumber) { groups[current] = groupNumber; foreach (var edge in graph[current]) { var next = edge.To.Index; if (next == parent || groups[next] != -1) { continue; } Dfs(next, current, groupNumber); } } var groupCount = 0; for (int i = 0; i < nodeCount; i++) { if (groups[i] == -1) { Dfs(i, -1, groupCount++); } } for (int i = 0; i < nodeCount; i++) { } }
public override void Solve(IOManager io) { var nodeCount = io.ReadInt(); var edgeCount = io.ReadInt(); var graph = new BasicGraph(nodeCount); var indegrees = new int[graph.NodeCount]; for (int i = 0; i < edgeCount; i++) { var s = io.ReadInt(); var t = io.ReadInt(); s--; t--; graph.AddEdge(s, t); indegrees[t]++; } var result = double.MaxValue; for (int block = 0; block < graph.NodeCount; block++) { result.ChangeMin(GetExpectation(block)); } io.WriteLine(result); double GetExpectation(int block) { Span <double> dp = stackalloc double[graph.NodeCount]; dp[^ 1] = 0;
public override IEnumerable <object> Solve(TextReader inputStream) { var nodeCount = inputStream.ReadInt(); var a = inputStream.ReadIntArray(); var graph = new BasicGraph(nodeCount); for (int i = 0; i < nodeCount - 1; i++) { var(u, v) = inputStream.ReadValue <int, int>(); u--; v--; graph.AddEdge(new BasicEdge(u, v)); graph.AddEdge(new BasicEdge(v, u)); } var dp = Enumerable.Repeat(int.MaxValue, nodeCount).ToArray(); var results = new int[nodeCount]; void Dfs(int current, int parent) { var index = SearchExtensions.GetGreaterEqualIndex(dp, a[current]); var last = dp[index]; dp[index] = a[current]; results[current] = SearchExtensions.GetLessThanIndex(dp, int.MaxValue); foreach (var edge in graph[current]) { var next = edge.To.Index; if (next != parent) { Dfs(next, current); } } dp[index] = last; } Dfs(0, -1); for (int i = 0; i < results.Length; i++) { yield return(results[i] + 1); } }
public override IEnumerable <object> Solve(TextReader inputStream) { var n = inputStream.ReadInt(); tree = new BasicGraph(n); for (int i = 0; i < n - 1; i++) { var(x, y) = inputStream.ReadValue <int, int>(); x--; y--; tree.AddEdge(new BasicEdge(x, y)); tree.AddEdge(new BasicEdge(y, x)); } var(whites, blacks) = Dfs(0, -1); yield return(whites + blacks); }
public override IEnumerable <object> Solve(TextReader inputStream) { var n = inputStream.ReadInt(); graph = new BasicGraph(n); for (int i = 0; i < n - 1; i++) { var(a, b) = inputStream.ReadValue <int, int>(); a--; b--; graph.AddEdge(new BasicEdge(a, b)); graph.AddEdge(new BasicEdge(b, a)); } var painter = new Painter(graph); var count = painter.Search(new BasicNode(0)); yield return((count[0, 0] + count[0, 1]).Value); }
public override IEnumerable <object> Solve(TextReader inputStream) { var n = inputStream.ReadInt(); tree = new BasicGraph(n); for (int i = 0; i < n - 1; i++) { var(x, y) = inputStream.ReadValue <int, int>(); x--; y--; tree.AddEdge(new BasicEdge(x, y)); tree.AddEdge(new BasicEdge(y, x)); } depthAndIndices = new List <DepthAndIndex>(); firstIndices = new int[n]; depthes = new int[n]; EularTour(new BasicNode(0), new BasicNode(-1), 0); var segTree = new SegmentTree <DepthAndIndex>(depthAndIndices); var queries = inputStream.ReadInt(); for (int q = 0; q < queries; q++) { var(a, b) = inputStream.ReadValue <int, int>(); a--; b--; var indexA = firstIndices[a]; var indexB = firstIndices[b]; if (indexA > indexB) { (indexA, indexB) = (indexB, indexA); } var lca = segTree.Query(indexA, indexB + 1).Index; yield return(depthes[a] + depthes[b] - 2 * depthes[lca] + 1); } }
public override void Solve(IOManager io) { var nodes = io.ReadInt(); var graph = new BasicGraph(nodes); for (int i = 0; i < nodes - 1; i++) { var a = io.ReadInt() - 1; var b = io.ReadInt() - 1; graph.AddEdge(new BasicEdge(a, b)); graph.AddEdge(new BasicEdge(b, a)); } var costs = io.ReadIntArray(nodes); Array.Sort(costs, (a, b) => b - a); var queue = new Queue <int>(costs); var results = new int[nodes]; Dfs(0, -1); io.WriteLine(costs.Sum() - costs.Max()); io.WriteLine(results, ' '); void Dfs(int current, int parent) { results[current] = queue.Dequeue(); foreach (var edge in graph[current]) { var next = edge.To.Index; if (next != parent) { Dfs(next, current); } } } }
public override void Solve(IOManager io) { Modular.InitializeCombinationTable(); var n = io.ReadInt(); var tree = new BasicGraph(n); for (int i = 0; i < n - 1; i++) { var a = io.ReadInt() - 1; var b = io.ReadInt() - 1; tree.AddEdge(a, b); tree.AddEdge(b, a); } var rerooting = new Rerooting <BasicEdge, CountAndWay>(tree); var results = rerooting.Solve(); foreach (var r in results) { io.WriteLine(r.Way); } }
public override IEnumerable <object> Solve(TextReader inputStream) { Modular.InitializeCombinationTable(); var nodeCount = inputStream.ReadInt(); var graph = new BasicGraph(nodeCount); for (int i = 0; i < nodeCount - 1; i++) { var(u, v) = inputStream.ReadValue <int, int>(); u--; v--; graph.AddEdge(new BasicEdge(u, v)); graph.AddEdge(new BasicEdge(v, u)); } var rerooting = new Rerooting <BasicNode, BasicEdge, CountAndWay>(graph); var results = rerooting.Solve(); foreach (var result in results) { yield return(result.Way); } }
public static BasicGraph Do(string filePath) { Console.WriteLine("Reading file {0}", filePath); if (!File.Exists(filePath)) { throw new Exception(string.Format("File {0} does not exist. Will not continue.", filePath)); } var lines = File.ReadAllLines(filePath); var index = 0; var graph = new BasicGraph(); foreach (var line in lines) { index++; if (string.IsNullOrWhiteSpace(line)) { continue; } Console.WriteLine("Parsing line {0}.", index); var triplet = line.Split(',').Select(x => x.Trim()).ToList(); if (triplet.Count() != 3) { Console.WriteLine(" Invalid format, skipping."); continue; } var left = triplet[0]; var right = triplet[1]; double weight; if (!Double.TryParse(triplet[2], out weight)) { Console.WriteLine(" Could not parse weight, skipping."); continue; } Console.WriteLine(" Parsed Edge {0}<->{1} with a weight of {2}", left, right, weight); graph.AddEdge(left, right, weight); } Console.WriteLine("Parsing complete."); return(graph); }
public override void Solve(IOManager io) { var n = io.ReadInt(); var x = io.ReadInt() - 1; var tree = new BasicGraph(n); var jewels = io.ReadIntArray(n).Select(b => b == 1).ToArray(); for (int i = 0; i < n - 1; i++) { var a = io.ReadInt(); var b = io.ReadInt(); a--; b--; tree.AddEdge(a, b); tree.AddEdge(b, a); } Dfs(x, -1); io.WriteLine(Math.Max((jewels.Count(b => b) - 1) * 2, 0)); bool Dfs(int current, int parent) { var hasJewel = jewels[current]; foreach (var next in tree[current]) { if (parent != next) { hasJewel |= Dfs(next, current); } } return(jewels[current] = hasJewel); } }
public override IEnumerable <object> Solve(TextReader inputStream) { var(n, m) = inputStream.ReadValue <int, int>(); var heights = inputStream.ReadIntArray(); var graph = new BasicGraph(n); for (int i = 0; i < m; i++) { var(a, b) = inputStream.ReadValue <int, int>(); a--; b--; graph.AddEdge(new BasicEdge(a, b)); graph.AddEdge(new BasicEdge(b, a)); } var count = 0; for (int i = 0; i < heights.Length; i++) { var ok = true; foreach (var edge in graph[i]) { var to = edge.To.Index; if (heights[i] <= heights[to]) { ok = false; } } if (ok) { count++; } } yield return(count); }
public override IEnumerable <object> Solve(TextReader inputStream) { var(nodeCount, edgeCount) = inputStream.ReadValue <int, int>(); graph = new BasicGraph(nodeCount); colors = new Color[nodeCount]; for (int i = 0; i < edgeCount; i++) { var(a, b) = inputStream.ReadValue <int, int>(); a--; b--; graph.AddEdge(new BasicEdge(a, b)); graph.AddEdge(new BasicEdge(b, a)); } if (Paint()) { yield return((long)colors.Count(c => c == Color.Black) * colors.Count(c => c == Color.White) - edgeCount); } else { yield return((long)nodeCount * (nodeCount - 1) / 2 - edgeCount); } }
public override IEnumerable <object> Solve(TextReader inputStream) { var(rooms, paths) = inputStream.ReadValue <int, int>(); var dungeon = new BasicGraph(rooms); for (int i = 0; i < paths; i++) { var(a, b) = inputStream.ReadValue <int, int>(); a--; b--; dungeon.AddEdge(new BasicEdge(a, b)); dungeon.AddEdge(new BasicEdge(b, a)); } var solver = new BfsSolver(dungeon); var previous = solver.Search(new BasicNode(0)); yield return("Yes"); for (int i = 1; i < previous.Length; i++) { yield return(previous[i] + 1); } }
public override IEnumerable <object> Solve(TextReader inputStream) { var n = inputStream.ReadInt(); graph = new BasicGraph(n); for (int me = 1; me < n; me++) { var hostile = inputStream.ReadInt(); hostile--; graph.AddEdge(new BasicEdge(hostile, me)); } yield return(Dfs(0)); }
public override IEnumerable <object> Solve(TextReader inputStream) { var(n, m) = inputStream.ReadValue <int, int>(); var edges = new BasicEdge[n - 1 + m]; var graph = new BasicGraph(n); var inDegrees = new int[n]; var invertedGraph = new BasicGraph(n); for (int i = 0; i < edges.Length; i++) { var(from, to) = inputStream.ReadValue <int, int>(); from--; to--; var edge = new BasicEdge(from, to); edges[i] = edge; inDegrees[to]++; graph.AddEdge(edge); invertedGraph.AddEdge(new BasicEdge(to, from)); } var sortedNodes = TopologicalSort(graph, inDegrees); var sortedNodesPositions = new int[n]; for (int i = 0; i < sortedNodesPositions.Length; i++) { var node = sortedNodes[i]; sortedNodesPositions[node] = i; } for (int i = 0; i < n; i++) { var parents = invertedGraph[i].ToArray(); var answer = -1; var answerPosition = -1; foreach (var parent in parents) { var position = sortedNodesPositions[parent.To.Index]; if (answerPosition < position) { answerPosition = position; answer = parent.To.Index; } } yield return(answer + 1); } }
public override IEnumerable <object> Solve(TextReader inputStream) { var n = inputStream.ReadInt(); var graph = new BasicGraph(n * n); var indegrees = new int[graph.NodeCount]; for (int me = 0; me < n; me++) { var enemies = inputStream.ReadIntArray().Select(i => i - 1); var last = -1; foreach (var enemy in enemies) { if (last != -1) { var from = GetIndex(me, last, n); var to = GetIndex(me, enemy, n); graph.AddEdge(new BasicEdge(from, to)); indegrees[to]++; } last = enemy; } } var sorted = TopologicalSort(graph, indegrees); if (sorted == null) { yield return(-1); } else { var dp = new int[sorted.Count]; foreach (var currentNode in sorted) { foreach (var next in graph[currentNode]) { UpdateWhenLarge(ref dp[next.To.Index], dp[currentNode] + 1); } } var max = dp.Max() + 1; yield return(max); } }
public override void Solve(IOManager io) { var n = io.ReadInt(); var tree = new BasicGraph(n); var root = -1; for (int i = 0; i < n; i++) { var p = io.ReadInt(); if (p == -1) { root = i; } else { p--; tree.AddEdge(p, i); } } var lca = new LowestCommonAncester(tree, root); var queries = io.ReadInt(); for (int q = 0; q < queries; q++) { var staff = io.ReadInt() - 1; var boss = io.ReadInt() - 1; if (lca.GetLcaNode(staff, boss) == boss) { io.WriteLine("Yes"); } else { io.WriteLine("No"); } } }
public override IEnumerable <object> Solve(TextReader inputStream) { var n = inputStream.ReadInt(); tree = new BasicGraph(n); if (n == 1) { yield return("POSSIBLE"); yield break; } var p = inputStream.ReadIntArray().Select(pi => pi - 1).ToArray(); x = inputStream.ReadIntArray(); for (int i = 0; i < p.Length; i++) { var me = i + 1; tree.AddEdge(new BasicEdge(p[i], me)); } yield return(Dfs(0) != Sum.NG ? "POSSIBLE" : "IMPOSSIBLE"); }
public override void Solve(IOManager io) { var n = io.ReadInt(); var graph = new BasicGraph(n); var degrees = new int[n]; for (int i = 0; i < n - 1; i++) { var a = io.ReadInt(); var b = io.ReadInt(); graph.AddEdge(new BasicEdge(a, b)); graph.AddEdge(new BasicEdge(b, a)); degrees[a]++; degrees[b]++; } for (int i = 0; i < degrees.Length; i++) { if (degrees[i] > 2) { var result = Dfs(i, -1); io.WriteLine(result); return; } } io.WriteLine(1); int Dfs(int current, int parent) { var children = 0; var antennas = 0; var antennaBranches = 0; foreach (var edge in graph[current]) { var next = edge.To.Index; if (next == parent) { continue; } children++; var an = Dfs(next, current); antennas += an; if (an > 0) { antennaBranches++; } } if (children > antennaBranches + 1) { antennas += children - (antennaBranches + 1); } return(antennas); } }
protected override void PrepareSolution() { locationsToKeycodes = new Dictionary <string, uint>(); locationsToKeycodes.Add("@", 0); for (int a = 0; a < alphabet.Length; a++) { locationsToKeycodes.Add(alphabet[a].ToString(), (uint)1 << a); } keycodesToLocations = locationsToKeycodes.ToDictionary((kvp) => kvp.Value, (kvp) => kvp.Key); locationsToKeycodes.Add("0", 0); //Making sure that only keys have non-zero values locationsToKeycodes.Add("1", 0); locationsToKeycodes.Add("2", 0); locationsToKeycodes.Add("3", 0); var stringTilesByRowAndColumn = mazeRows.Select(row => row.Select(tile => tile.ToString())); var maze = new Maze <string>(stringTilesByRowAndColumn, "#", floors.Concat(keys).Select(tile => tile.ToString())); var floorsAndDoors = floors.Concat(doors).Select(tile => tile.ToString()).ToHashSet(); maze.EliminateDeadEnds(floorsAndDoors, "#", walls.Select(tile => tile.ToString()).ToHashSet()); var remainingKeysAndDoors = maze.GetAllTileTypes().ToHashSet(); remainingKeysAndDoors.ExceptWith(new string[] { "@", ".", "#" }); var quadRoots = new Dictionary <string, (int, int)>(); var centerTile = ((int x, int y))maze.FindFirstMatchingTile("@"); maze[centerTile.x, centerTile.y] = "#"; int intersectionCounter = 0; //Mark the corners around the center as intersections foreach (var direction in Direction.North.GetAll()) { var(x, y) = DirectionHelper.NeighbourInDirection(direction, centerTile.x, centerTile.y); if (x == centerTile.x || y == centerTile.y) { maze[x, y] = "#"; } else { maze[x, y] = intersectionCounter.ToString(); quadRoots.Add(intersectionCounter.ToString(), (x, y)); intersectionCounter++; } } var walkableTiles = floors.Concat(doors).Concat(keys).Select(tile => tile.ToString()); //Do a floodfill of the remaining maze, changing the tile-type every time we encounter a door/key/intersection //tile-types will be built as follows [].[].[] where each[] is a door/key/intersection number var intersectionBranches = new HashSet <string>(); var frontiers = new List <(int, int)>(quadRoots.Values); while (frontiers.Any()) { var nextFrontiers = new List <(int, int)>(); foreach (var(x, y) in frontiers) { var currentTileType = maze[x, y]; var relevantNeighbours = maze.GetNeighbours(x, y).Where(nb => walkableTiles.Contains(nb.Value)); var keysOrDoors = relevantNeighbours.Where(nb => keys.Contains(nb.Value) || doors.Contains(nb.Value)).ToList(); if (relevantNeighbours.Count() > 1) { //this is an intersection an edge ends here, and 2 or 3 new edges start maze[x, y] = $"{currentTileType}."; int branchCounter = 0; foreach (var nb in relevantNeighbours) { var(nbx, nby) = DirectionHelper.NeighbourInDirection(nb.Key, x, y); var intersectionBranch = $"{currentTileType}.{intersectionCounter}:{branchCounter}"; maze[nbx, nby] = intersectionBranch; branchCounter++; nextFrontiers.Add((nbx, nby)); intersectionBranches.Add(intersectionBranch); } intersectionCounter++; } else { if (relevantNeighbours.Any()) { var(nbx, nby) = DirectionHelper.NeighbourInDirection(relevantNeighbours.First().Key, x, y); maze[nbx, nby] = currentTileType; nextFrontiers.Add((nbx, nby)); } } foreach (var nb in keysOrDoors) { //next tile will be a key or door, meaning the edge of this frontier will end there var(nbx, nby) = DirectionHelper.NeighbourInDirection(nb.Key, x, y); var updatedCurrentTileType = maze[nbx, nby]; maze[nbx, nby] = $"{updatedCurrentTileType}.{nb.Value}"; } } frontiers = nextFrontiers; } //intersections are marked by a . as final character, this means each branch has a count of 1 less than it should be var tileCounts = new Dictionary <string, int>(maze.GetTileCounts().Where(tc => tc.Value > 0 && tc.Key.Last() != '.')); foreach (var intersectionBranch in intersectionBranches) { tileCounts.TryGetValue(intersectionBranch, out int value); tileCounts[intersectionBranch] = value + 1; } //Build a graph graph = new BasicGraph(); //Create nodes graph.AddNode("@"); foreach (var(tile, count) in tileCounts) { var splitTile = tile.Split('.'); var endpoint = splitTile.Last().Split(':'); if (!graph.ContainsNode(endpoint.First())) { graph.AddNode(endpoint.First()); } } keycodesToQuadrants = new Dictionary <uint, int>(); //Create edges & blockingsets blockingsetPerKey = new Dictionary <uint, uint>(); foreach (var(tile, _) in tileCounts) { var splitTile = tile.Split('.').Select(loc => loc.Split(':').First()).ToArray(); if (splitTile.Length > 1) { var from = splitTile[splitTile.Length - 2]; var to = splitTile[splitTile.Length - 1]; var lastPeriod = tile.LastIndexOf('.'); var edgeLength = tileCounts[tile.Substring(0, lastPeriod)]; graph.AddEdge(from, to, edgeLength); if (keys.Contains(to)) { var blockingKeys = splitTile.Take(splitTile.Length - 1).Select(nodeName => nodeName.ToLower()).Where(keyName => keys.Contains(keyName)).Distinct(); uint blockingCode = 0; foreach (var blockingKey in blockingKeys) { blockingCode = blockingCode | locationsToKeycodes[blockingKey]; } blockingsetPerKey.Add(locationsToKeycodes[to], blockingCode); keycodesToQuadrants.Add(locationsToKeycodes[to], int.Parse(splitTile.First())); } } } //Add edges between @,0,1,2,3 foreach (var quadrantStart in Enumerable.Range(0, 4).Select(q => q.ToString())) { graph.AddEdge("@", quadrantStart, 2); } graph.AddEdge("0", "1", 2); graph.AddEdge("1", "2", 2); graph.AddEdge("2", "3", 2); graph.AddEdge("3", "0", 2); }
public override void Solve(IOManager io) { const string Inf = "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"; var n = io.ReadInt(); var edgeCount = io.ReadInt(); var length = io.ReadInt(); var originalCharList = new char[n]; for (int i = 0; i < originalCharList.Length; i++) { originalCharList[i] = io.ReadChar(); } var originalGraph = new Internal.SCCGraph(n); var edges = new Edge[edgeCount]; for (int i = 0; i < edges.Length; i++) { var a = io.ReadInt(); var b = io.ReadInt(); a--; b--; edges[i] = new Edge(a, b); originalGraph.AddEdge(a, b); } var(groupCount, ids) = originalGraph.SCCIDs(); var graph = new BasicGraph(groupCount + 1); foreach (var(from, to) in edges) { if (ids[from] != ids[to]) { var contains = false; foreach (var next in graph[ids[from] + 1]) { contains |= next == ids[to] + 1; } if (!contains) { graph.AddEdge(ids[from] + 1, ids[to] + 1); } } } for (int i = 1; i < graph.NodeCount; i++) { graph.AddEdge(0, i); } var dp = new string[graph.NodeCount, length + 1]; dp.Fill(Inf); dp[0, 0] = ""; var charList = Enumerable.Repeat(0, graph.NodeCount).Select(_ => new List <char>()).ToArray(); for (int i = 0; i < originalCharList.Length; i++) { charList[ids[i] + 1].Add(originalCharList[i]); } foreach (var c in charList) { c.Sort(); } for (int i = 0; i < graph.NodeCount; i++) { for (int l = 0; l <= length; l++) { foreach (var next in graph[i]) { var newString = dp[i, l]; if (newString == Inf) { continue; } ChangeMin(ref dp[next, l], newString); for (int append = 0; append < charList[next].Count; append++) { newString += charList[next][append]; if (newString.Length <= length) { ChangeMin(ref dp[next, newString.Length], newString); } else { break; } } } } } var result = Inf; for (int i = 0; i < graph.NodeCount; i++) { ChangeMin(ref result, dp[i, length]); } if (result != Inf) { io.WriteLine(result); } else { io.WriteLine(-1); } }
public override void Solve(IOManager io) { var n = io.ReadInt(); var tree = new BasicGraph(n); var edgeIndice = new Dictionary <Edge, int>(n); for (int i = 0; i < n - 1; i++) { var u = io.ReadInt(); var v = io.ReadInt(); u--; v--; tree.AddEdge(u, v); tree.AddEdge(v, u); edgeIndice[new Edge(u, v)] = i; } var pathCount = io.ReadInt(); var paths = new Path[pathCount]; for (int i = 0; i < paths.Length; i++) { var u = io.ReadInt(); var v = io.ReadInt(); u--; v--; paths[i] = new Path(u, v); } var pathFlags = new uint[n - 1]; for (int i = 0; i < pathCount; i++) { InitDfs(0, -1, i); } var dp = DpDfs(0, -1); io.WriteLine(dp[(1 << pathCount) - 1]); State InitDfs(int current, int parent, int pathIndex) { foreach (var next in tree[current]) { if (next == parent) { continue; } var state = InitDfs(next, current, pathIndex); if (state == State.None) { if (next == paths[pathIndex].From) { pathFlags[edgeIndice[new Edge(current, next)]] |= 1u << pathIndex; return(State.FirstFound); } else if (next == paths[pathIndex].To) { pathFlags[edgeIndice[new Edge(current, next)]] |= 1u << pathIndex; return(State.SecondFound); } } else if (state == State.Completed) { return(State.Completed); } else if (state == State.FirstFound) { pathFlags[edgeIndice[new Edge(current, next)]] |= 1u << pathIndex; if (paths[pathIndex].To == current) { return(State.Completed); } else { return(State.FirstFound); } } else if (state == State.SecondFound) { pathFlags[edgeIndice[new Edge(current, next)]] |= 1u << pathIndex; if (paths[pathIndex].From == current) { return(State.Completed); } else { return(State.SecondFound); } } } return(State.None); } long[] DpDfs(int current, int parent) { var dp = new long[1 << pathCount]; if (tree[current].Length == 1 && parent != -1) { dp[0] = 1; return(dp); } foreach (var next in tree[current]) { if (next == parent) { continue; } var currentPathFlag = pathFlags[edgeIndice[new Edge(current, next)]]; var childDp = DpDfs(next, current); for (var flag = BitSet.Zero; flag < 1 << pathCount; flag++) { // 黒くする dp[flag | currentPathFlag] += childDp[flag]; // 白くする dp[flag] += childDp[flag]; } } return(dp); } }