using System; using System.Collections.Generic; using System.IO; using System.Text; namespace ProjEuler { public class ACM2008_LSU_Problem8 { public static void Main() { using(TextWriter writer=new StreamWriter("output.txt")) using (TextReader reader = new StreamReader("input.txt")) { Console.SetOut(writer); int n = ReadInt(reader); for (int i = 0; i < n; i++) ProcessProblem(i+1, reader); } } public static void ProcessProblem(int id, TextReader input) { Console.Error.WriteLine(id); Console.WriteLine("DATA SET #" + id); Timeline timeline = new Timeline(); int wormHoleCount = ReadInt(input); for (int i = 0; i < wormHoleCount; i++) timeline.AddWormhole(ReadInts(input)); int startingYear = ReadInt(input); int missionCount = ReadInt(input); for (int m = 0; m < missionCount; m++) { int destination = ReadInt(input); int distance = timeline.ShortestPath(startingYear, destination); int returnDistance = timeline.ShortestPath(destination, startingYear); if(distance==Int32.MaxValue || returnDistance==Int32.MaxValue) Console.WriteLine("IMPOSSIBLE"); else Console.WriteLine(distance+returnDistance); } } private static int ReadInt(TextReader reader) { return Int32.Parse(reader.ReadLine()); } private static int[] ReadInts(TextReader reader) { string text = reader.ReadLine(); string[] numbers = text.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); int[] result=new int[numbers.Length]; for (int i = 0; i < numbers.Length; i++) result[i] = Int32.Parse(numbers[i]); return result; } } class Timeline { private List wormholes=new List(); public void AddWormhole(int[] wormhole) { wormholes.Add(wormhole); } public int ShortestPath(int sourceYear, int destYear) { List edges = new List(); List vertexes=new List(); vertexes.Add(sourceYear); vertexes.Add(destYear); foreach (int[] wormhole in wormholes) { vertexes.Add(wormhole[0]); vertexes.Add(wormhole[1]); edges.Add(new Edge(wormhole[0], wormhole[1], true)); } vertexes.Sort(); for (int i = 1; i < vertexes.Count; i++) if (vertexes[i] == vertexes[i - 1]) vertexes.RemoveAt(i--); for (int i = 1; i < vertexes.Count; i++) edges.Add(new Edge(vertexes[i - 1], vertexes[i], false)); Dictionary distances = new Dictionary(); distances[sourceYear] = 0; for (int i = 0; i < vertexes.Count; i++ ) foreach (Edge edge in edges) { if (!distances.ContainsKey(edge.start)) continue; int distance = distances[edge.start] + edge.weight; if (!distances.ContainsKey(edge.end) || distances[edge.end] > distance) distances[edge.end] = distance; } if (distances.ContainsKey(destYear)) return distances[destYear]; return Int32.MaxValue; } } class Edge { public int start, end, weight; public Edge(int startYear, int endYear, bool isWormhole) { start = startYear; end = endYear; if (!isWormhole) weight = endYear - startYear; else if (endYear > startYear) weight = (endYear - startYear) / 2; else weight = (endYear - startYear) / 4; } } }