using System; using System.Collections.Generic; using System.IO; using System.Linq; class Solution { internal class Node { public Node(int val) { Value = val; In = new List(); Out = new List(); } public int Value; public List In; public List Out; } internal class Edge { public char Type; public int To; public int From; } internal class Graph { public List Nodes; public List Edges; internal Graph() { Nodes = new List(); Edges = new List(); } private Node GetByValue(int val) { return Nodes.First(n => n.Value == val); } private Node GetOrAddNode(int i) { var node = Nodes.FirstOrDefault(n => n.Value == i); if (node == null) { node = new Node(i); Nodes.Add(node); } return node; } public void AddEdge(int start, int end, char type) { var fromNode = GetOrAddNode(start); var toNode = GetOrAddNode(end); var edge = new Edge() { Type = type, To = end, From = start }; Edges.Add(edge); fromNode.Out.Add(edge); toNode.In.Add(edge); } internal int CountWithRules(IEnumerable edges) { int cats = 0; int dogs = 0; int elephants = 0; int mice = 0; foreach (var e in edges) switch (char.ToLower(e.Type)) { case 'e': elephants++; break; case 'c': cats++; break; case 'm': mice++; break; case 'd': dogs++; break; default: // Should throw? break; } // Maybe just max of the sums is all we need? return Math.Max(dogs, Math.Max(cats, Math.Max(elephants, Math.Max(mice, Math.Max(dogs + mice, elephants + cats))))); } internal int SearchMin(int animalsWanted) { // First node Node[] nodesInOrder = Nodes.OrderBy(x => x.Value).ToArray(); int animalCount = 0; int lastZooToVisit = -1; for (var i = 0; i < nodesInOrder.Length; i++) { // See if we can satisfy the requirements with the edges on the current Node lastZooToVisit = nodesInOrder[i].Out.Count > 0 ? nodesInOrder[i].Out.Max(n => n.To) : -1; var currentCount = CountWithRules(nodesInOrder[i].Out.Concat(Edges.Where(e => e.From >= nodesInOrder[i].Value && e.To <= lastZooToVisit)).Distinct()); if (animalCount + currentCount >= animalsWanted) return lastZooToVisit; // Need more, can we continue? Look forward to see the next node // If behind the if (i + 1 < nodesInOrder.Length && nodesInOrder[i + 1].Value >= lastZooToVisit) { // continue accumulating animals animalCount += currentCount; } else { // Need to restart from the next node animalCount = 0; } //while (i + 1 < nodesInOrder.Length && lastZooToVisit > nodesInOrder[i+1].Value) // i++; } return animalCount >= animalsWanted ? lastZooToVisit : -1; } } public static int[] minimumZooNumbers(int m, int n, char[] t, int[] s, int[] d) { // Return a list of length n consisting of the answers Graph g = new Graph(); // Construct nodes for (var i = 0; i < n; i++) { g.AddEdge(s[i], d[i], t[i]); } int[] results = new int[n]; for (var i = 1; i <= n; i++) { // Start at initial node // See how many animals are there (# edges - constraints) results[i - 1] = g.SearchMin(i); // Return lowest node with # of connected edges } return results; } static void Main(String[] args) { int cases = Convert.ToInt32(Console.ReadLine()); for(int a0 = 0; a0 < cases; a0++){ string[] tokens_m = Console.ReadLine().Split(' '); int m = Convert.ToInt32(tokens_m[0]); int n = Convert.ToInt32(tokens_m[1]); string[] t_temp = Console.ReadLine().Split(' '); char[] t = Array.ConvertAll(t_temp,Char.Parse); string[] s_temp = Console.ReadLine().Split(' '); int[] s = Array.ConvertAll(s_temp,Int32.Parse); string[] d_temp = Console.ReadLine().Split(' '); int[] d = Array.ConvertAll(d_temp,Int32.Parse); int[] result = minimumZooNumbers(m, n, t, s, d); Console.WriteLine(String.Join(" ", result)); } } }