예제 #1
0
    static long Calc(long n)
    {
        if (n == 1)
            return 0;

        var queue = new OrderedBag<State>((pair1, pair2) =>
            pair1.Value.CompareTo(pair2.Value)
        );

        queue.Add(new State(n, 0));

        while (queue.Count != 0)
        {
            var currentState = queue.RemoveFirst();

            if (currentState.Key == 1)
                return currentState.Value;

            for (int power = 2; power < 60; power++)
            {
                var powerBase = Math.Pow(currentState.Key, 1.0 / power);

                var nextNumber = (long)Math.Round(powerBase);
                var nextSteps = Math.Abs(Pow(nextNumber, power) - currentState.Key);

                var nextState = new State(nextNumber, currentState.Value + nextSteps + 1);
                queue.Add(nextState);
            }
        }

        throw new ArgumentException();
    }
예제 #2
0
    private static IList<int> Dijkstra(int start)
    {
        var distances = Enumerable.Repeat(int.MaxValue, graph.Count).ToArray();

        var queue = new OrderedBag<Node>((node1, node2) =>
            node1.Distance.CompareTo(node2.Distance)
        );

        distances[start] = 0;
        queue.Add(new Node(start, 0));

        while (queue.Count != 0)
        {
            var currentNode = queue.RemoveFirst();

            foreach (var neighborNode in graph[currentNode.To])
            {
                int currentDistance = distances[currentNode.To] + neighborNode.Distance;

                if (currentDistance < distances[neighborNode.To])
                {
                    distances[neighborNode.To] = currentDistance;
                    queue.Add(new Node(neighborNode.To, currentDistance));
                }
            }

            // Removing repeating is actually slower?
        }

        return distances;
    }
        static void DijkstraFindMinCableLengthBetweenHouses(Dictionary<HouseNode, 
            List<CableConnection>> graph, HouseNode houseToStartFrom)
        {
            OrderedBag<HouseNode> houseQueue = new OrderedBag<HouseNode>();

            foreach (var house in graph)
            {
                house.Key.MinCableLenth = int.MaxValue;
            }

            houseToStartFrom.MinCableLenth = 0;
            houseQueue.Add(houseToStartFrom);

            while (houseQueue.Count > 0)
            {
                var currentHouse = houseQueue.RemoveFirst();

                if (currentHouse.MinCableLenth == int.MaxValue)
                {
                    break;
                }

                foreach (var connection in graph[currentHouse])
                {
                    var currentCableLength = currentHouse.MinCableLenth + connection.CableLenth;
                    if (connection.House.MinCableLenth > currentCableLength)
                    {
                        connection.House.MinCableLenth = currentCableLength;
                        houseQueue.Add(connection.House);
                    }
                }
            }
        }
        static void DijkstraAlgorithm(Node[] graph, Node source)
        {
            var priority = new OrderedBag<Node>();

            for (int i = 1; i < graph.Length; i++)
            {
                graph[i].DijkstraDistance = int.MaxValue;
            }

            source.DijkstraDistance = 0;
            priority.Add(source);

            while (priority.Count != 0)
            {
                Node currentNode = priority.RemoveFirst();

                if (currentNode.DijkstraDistance == int.MaxValue)
                {
                    break;
                }

                for (int i = 0; i < currentNode.Edges.Count; i++)
                {
                    int potDistance = currentNode.DijkstraDistance + currentNode.Edges[i].Weight;

                    if (potDistance < graph[currentNode.Edges[i].NodeId].DijkstraDistance)
                    {
                        graph[currentNode.Edges[i].NodeId].DijkstraDistance = potDistance;
                        priority.Add(graph[currentNode.Edges[i].NodeId]);
                    }
                }
            }
        }
예제 #5
0
        public static void Main(string[] args)
        {
            for (int i = 0; i < 4; i++)
            {
                var start = new KeyValuePair<BigInteger, int>(1, 0);
                BigInteger desired = BigInteger.Parse(Console.ReadLine());
                var results = new OrderedBag<KeyValuePair<BigInteger, int>>((x, y) => x.Value.CompareTo(y.Value));
                results.Add(start);

                var current = start;

                HashSet<BigInteger> used = new HashSet<BigInteger>();
                while (current.Key != desired)
                {
                    current = results.RemoveFirst();
                    if (!used.Contains(current.Key))
                    {
                        results.Add(new KeyValuePair<BigInteger, int>(current.Key + 1, current.Value + 1));

                        if (current.Key != 1)
                        {
                            BigInteger toPower = 1;
                            List<BigInteger> powers = new List<BigInteger>();
                            while (toPower <= desired - 1)
                            {
                                toPower *= current.Key;
                                powers.Add(toPower);
                            }

                            powers.Reverse();

                            foreach (var item in powers)
                            {
                                if (item <= desired + 1 && !used.Contains(item))
                                {
                                    if (!used.Contains(item))
                                    {
                                        results.Add(new KeyValuePair<BigInteger, int>(item, current.Value + 1));
                                    }

                                    if (!used.Contains(item - 1))
                                    {
                                        results.Add(new KeyValuePair<BigInteger, int>(item - 1, current.Value + 2));
                                    }
                                }
                            }
                        }

                        used.Add(current.Key);
                    }
                }

                Console.WriteLine(current.Value);
            }
        }
예제 #6
0
        static public Questionnaire Run()
        {
            Questionnaire questionnaire = new Questionnaire();
            OrderedBag<Grille> OPEN = new OrderedBag<Grille>();
            OrderedBag<Grille> CLOSE = new OrderedBag<Grille>();
            Grille S = new Grille();
            OPEN.Add(S);
            while (OPEN.Count != 0)
            {
                Grille n = OPEN.RemoveFirst();
                CLOSE.Add(n);
                questionnaire.solutionsExplorer.Add(n.getStringEtat());
                if (n.getDistanceSolution() == 0)
                {
                    questionnaire.solutionMot = n.getSolutionMot();
                    questionnaire.solutionVisuelle = n.getSolutionVisuelle();
                    for (int i = 0; i < questionnaire.solutionVisuelle.Count; i++)
                    {

                        Console.Write("\n---Étape" + i + "----\n" +  questionnaire.solutionVisuelle[i] + "----------");
                    }
                    return questionnaire;
                }
                foreach (Grille nPrime in n.getListSuccessor())
                {
                    questionnaire.etatExplorer.Add(nPrime.getStringEtat());
                    if (Contient(OPEN, nPrime) != -1)
                    {
                        int position = Contient(OPEN, nPrime);
                        if (nPrime.getTotalDistance() < OPEN[position].getTotalDistance())
                        {
                            OPEN.Remove(OPEN[position]);
                            OPEN.Add(nPrime);
                        }
                    }
                    else if (Contient(CLOSE, nPrime) != -1)
                    {
                        int position = Contient(CLOSE, nPrime);
                        if (nPrime.getTotalDistance() < CLOSE[position].getTotalDistance())
                        {
                            CLOSE.Remove(CLOSE[position]);
                            OPEN.Add(nPrime);
                        }
                    }
                    else // Ni dans Close , ni dans OPEN
                    {
                        OPEN.Add(nPrime);
                    }
                }
            }
            questionnaire.solutionMot = "Aucun chemin possible";
            return questionnaire;
        }
예제 #7
0
    // Almost the same as Programming/5.DataStructuresAndAlgorithms/AlgoAcademy/4.DataStructures/2.Zadachi/Program.cs
    static void Main()
    {
#if DEBUG
        Console.SetIn(new System.IO.StreamReader("../../input.txt"));
#endif

        var date = DateTime.Now;

        var tasks = new OrderedBag<Tuple<string, int>>((task1, task2) =>
        {
            int compared = 0;

            compared = task1.Item2.CompareTo(task2.Item2);
            if (compared != 0) return compared;

            compared = task1.Item1.CompareTo(task2.Item1);
            if (compared != 0) return compared;

            return compared;
        });

        var output = new StringBuilder();

        var separator = new char[] { ' ' };

        foreach (int i in Enumerable.Range(0, int.Parse(Console.ReadLine())))
        {
            string line = Console.ReadLine();

            if (line == "Solve")
            {
                if (tasks.Count == 0)
                    output.AppendLine("Rest");

                else
                    output.AppendLine(tasks.RemoveFirst().Item1);
            }

            else
            {
                var match = line.Split(separator, 3);

                tasks.Add(new Tuple<string, int>(match[2], int.Parse(match[1])));
            }
        }

        Console.Write(output);

#if DEBUG
        Console.WriteLine(DateTime.Now - date);
#endif
    }
예제 #8
0
        public static long GetMinimalConnectionCost(string[] input)
        {
            var graph = new Dictionary<int, List<Edge>>();

            foreach (var edge in input)
            {
                var parts = edge.Split();
                var from = int.Parse(parts[0]);
                var to = int.Parse(parts[1]);
                var cost = int.Parse(parts[2]);

                InitializeIfNeeded(graph, from);
                InitializeIfNeeded(graph, to);

                graph[from].Add(new Edge(from, to, cost));
                graph[to].Add(new Edge(to, from, cost));
            }

            var startNode = graph.First().Key;

            var priorityQueue = new OrderedBag<Edge>();

            foreach (var neighbour in graph[startNode])
            {
                priorityQueue.Add(neighbour);
            }

            var cables = new List<Edge>();

            var visitedNodes = new HashSet<int> { startNode };

            while (priorityQueue.Count > 0)
            {
                var min = priorityQueue.RemoveFirst();

                if (visitedNodes.Contains(min.To))
                {
                    continue;
                }

                cables.Add(min);

                visitedNodes.Add(min.To);

                foreach (var neighbour in graph[min.To])
                {
                    priorityQueue.Add(neighbour);
                }
            }

            return cables.Sum(c => c.Cost);
        }
예제 #9
0
        public IEnumerable<Point> FindPath(Point start, Point goal)
        {
            var startNode = Map[start.Row][start.Column];
            var targetNode = Map[goal.Row][goal.Column];

            var openNodes = new OrderedBag<Node>(PathComparison);
            var closedNodes = new HashSet<Node>();
            openNodes.Add(startNode);

            while (openNodes.Count > 0)
            {
                var currentNode = openNodes.RemoveFirst();
                closedNodes.Add(currentNode);

                if (currentNode == targetNode)
                {
                    return tracePath(targetNode);
                }

                var neighbours = getNeighbours(currentNode);
                foreach (var neighbour in neighbours)
                {
                    if (!neighbour.IsWalkable || closedNodes.Contains(neighbour))
                    {
                        continue;
                    }

                    var newCost = currentNode.GainedCost + getCost(currentNode, neighbour);
                    if (newCost < neighbour.GainedCost || !openNodes.Contains(neighbour))
                    {
                        neighbour.GainedCost = newCost;
                        neighbour.HeuristicCost = getDistance(neighbour, targetNode);
                        neighbour.Parent = currentNode;

                        if (!openNodes.Contains(neighbour))
                        {
                            openNodes.Add(neighbour);
                        }
                    }
                }
            }

            //a path doesn't exist
            return new List<Point>();
        }
예제 #10
0
        private static int GetDistanceToHouses(Node hospital)
        {
            foreach (var node in map)
            {
                node.Key.DijkstraDistance = int.MaxValue;
            }

            hospital.DijkstraDistance = 0;

            var nodes = new OrderedBag<Node>();
            nodes.Add(hospital);

            while (nodes.Count > 0)
            {
                var currentNode = nodes.RemoveFirst();
                if (currentNode.DijkstraDistance == int.MaxValue)
                {
                    break;
                }

                foreach (var edge in map[currentNode])
                {
                    int potentialDistance = currentNode.DijkstraDistance + edge.Distance;
                    if (potentialDistance < edge.Destination.DijkstraDistance)
                    {
                        edge.Destination.DijkstraDistance = potentialDistance;
                        nodes.Add(edge.Destination);
                    }
                }
            }

            int distanceToHomes = 0;
            foreach (var point in map)
            {
                if (!point.Key.IsHospital && point.Key.DijkstraDistance != int.MaxValue)
                {
                    distanceToHomes += point.Key.DijkstraDistance;
                }
            }

            return distanceToHomes;
        }
예제 #11
0
        public static void Main()
        {
            #if DEBUG
            Console.SetIn(new System.IO.StreamReader("../../input2.txt"));
            #endif

            OrderedBag<Task> tasks = new OrderedBag<Task>((a, b) => {
                int compared = a.Item1.CompareTo(b.Item1);
                if (compared != 0)
                {
                    return compared;
                }

                return a.Item2.CompareTo(b.Item2);
            });

            StringBuilder result = new StringBuilder();
            int commandsList = int.Parse(Console.ReadLine());
            for (int i = 0; i < commandsList; i++)
            {
                string line = Console.ReadLine();
                string[] commandParts = line.Split(new char[]{' '}, 3);
                if (commandParts[0] == "New")
                {
                    int priority = int.Parse(commandParts[1]);
                    string taskName = commandParts[2];
                    tasks.Add(new Task(priority, taskName));
                }
                else if (commandParts[0] == "Solve")
                {
                    if (tasks.Count == 0)
                    {
                        result.AppendLine("Rest");
                        continue;
                    }
                    Task min = tasks.RemoveFirst();
                    result.AppendLine(min.Item2);
                }
            }

            Console.Write(result.ToString());
        }
예제 #12
0
        private static int GetDistanceToHomes(Point hospital)
        {
            foreach (var point in map)
            {
                point.Key.DijkstraDistance = int.MaxValue;
            }

            hospital.DijkstraDistance = 0;

            OrderedBag<Point> points = new OrderedBag<Point>();
            points.Add(hospital);
            while (points.Count > 0)
            {
                Point currentPoint = points.RemoveFirst();
                if (currentPoint.DijkstraDistance == int.MaxValue)
                {
                    break;
                }

                foreach (Connection connection in map[currentPoint])
                {
                    int potentialDistance = currentPoint.DijkstraDistance + connection.Distance;
                    if (potentialDistance < connection.Destination.DijkstraDistance)
                    {
                        connection.Destination.DijkstraDistance = potentialDistance;
                        points.Add(connection.Destination);
                    }
                }
            }

            int distanceToHomes = 0;
            foreach (var point in map)
            {
                if (!point.Key.IsHospital && point.Key.DijkstraDistance != int.MaxValue)
                {
                    distanceToHomes += point.Key.DijkstraDistance;
                }
            }

            return distanceToHomes;
        }
        private static void UseDijkstraAlgorithm(Junction startJunction)
        {
            OrderedBag <Junction> junctions = new OrderedBag <Junction>();

            startJunction.Cost = 0;
            junctions.Add(startJunction);
            while (junctions.Count > 0)
            {
                Junction currentJunction = junctions.RemoveFirst();
                currentJunction.IsVisited = true;
                foreach (Junction child in currentJunction.Children.Keys)
                {
                    if (!child.IsVisited)
                    {
                        if (child.Cost > currentJunction.Cost + currentJunction.Children[child])
                        {
                            child.Previous = currentJunction;
                            child.Cost     = currentJunction.Cost + currentJunction.Children[child];
                            junctions.Add(child);
                        }
                    }
                }
            }
        }
예제 #14
0
        private static void FindPath(int source, int destination,
                                     double[] distances, int[] prev)
        {
            var queue = new OrderedBag <int>
                            (Comparer <int> .Create((f, s) => (int)distances[f] - (int)distances[s]));

            queue.Add(source);
            distances[source] = 0;
            while (queue.Count > 0)
            {
                var node = queue.RemoveFirst();
                if (node == destination)
                {
                    break;
                }
                foreach (var edge in graph[node])
                {
                    int child = edge.From == node
                        ? edge.To
                        : edge.From;
                    if (double.IsPositiveInfinity(distances[child]))
                    {
                        queue.Add(child);
                    }
                    var newDistance = edge.Weight + distances[node];
                    if (newDistance < distances[child])
                    {
                        distances[child] = newDistance;
                        prev[child]      = node;
                        queue            = new OrderedBag <int>
                                               (queue, Comparer <int>
                                               .Create((f, s) => (int)distances[f] - (int)distances[s]));
                    }
                }
            }
        }
        private static int Prim(int budget)
        {
            var usedBudget = 0;

            var queue = new OrderedBag <Edge>
                            (Comparer <Edge> .Create((f, s) => f.Weight - s.Weight));

            foreach (var node in spaningTree)
            {
                queue.AddMany(graph[node]);
            }

            while (queue.Any())
            {
                var edge        = queue.RemoveFirst();
                var nonTreeNode = GetNonTreeNode(edge);

                if (nonTreeNode == -1)
                {
                    continue;
                }

                if (edge.Weight > budget)
                {
                    break;
                }

                usedBudget += edge.Weight;
                budget     -= edge.Weight;

                spaningTree.Add(nonTreeNode);
                queue.AddMany(graph[nonTreeNode]);
            }

            return(usedBudget);
        }
예제 #16
0
        public static List<Edge<int>> GetMinimalspanningTreeUsingPrim(List<Edge<int>> graph, int start)
        {
            var result = new List<Edge<int>>();
            var priority = new OrderedBag<Edge<int>>();
            var visited = new HashSet<int>();
            visited.Add(start);
            foreach (var edge in graph)
            {
                if (edge.Start == start || edge.End == start)
                {
                    priority.Add(edge);
                }
            }

            while (priority.Count > 0)
            {
                var current = priority.RemoveFirst();
                if (!(visited.Contains(current.Start) && visited.Contains(current.End)))
                {
                    result.Add(current);
                }

                if (visited.Contains(current.Start) && !visited.Contains(current.End))
                {
                    priority.AddMany(graph.Where(x => x.Start == current.End || x.End == current.End));
                    visited.Add(current.End);
                }
                else if (!visited.Contains(current.Start) && visited.Contains(current.End))
                {
                    priority.AddMany(graph.Where(x => x.Start == current.Start || x.End == current.Start));
                    visited.Add(current.Start);
                }
            }

            return result;
        }
예제 #17
0
        private static int Prim(int budget)
        {
            var costedBudget = 0;
            var queue        = new OrderedBag <Node>
                                   (Comparer <Node> .Create((f, s) => f.Weight - s.Weight));

            foreach (var edge in spanningTree)
            {
                queue.AddMany(graph[edge]);
            }

            while (queue.Count > 0)
            {
                var curNod = queue.RemoveFirst();

                var actualNode = GetActualNode(curNod);

                if (actualNode == -1)
                {
                    continue;
                }

                if (budget < curNod.Weight)
                {
                    break;
                }

                budget       -= curNod.Weight;
                costedBudget += curNod.Weight;

                spanningTree.Add(actualNode);
                queue.AddMany(graph[actualNode]);
            }

            return(costedBudget);
        }
예제 #18
0
        private static List <Cable> Prim(Dictionary <int, List <Cable> > graph)
        {
            var minSpanningTree = new List <Cable>();

            var startHouse = graph.First().Key;

            var orderedCables = new OrderedBag <Cable>();

            foreach (var cable in graph[startHouse])
            {
                orderedCables.Add(cable);
            }

            var visitedHouses = new HashSet <int>();

            visitedHouses.Add(startHouse);

            while (orderedCables.Count > 0)
            {
                var minCostCable = orderedCables.RemoveFirst();
                if (visitedHouses.Contains(minCostCable.ToHouse))
                {
                    continue;
                }

                minSpanningTree.Add(minCostCable);
                visitedHouses.Add(minCostCable.ToHouse);

                foreach (var cable in graph[minCostCable.ToHouse])
                {
                    orderedCables.Add(cable);
                }
            }

            return(minSpanningTree);
        }
예제 #19
0
    static long Calc(long n)
    {
        if (n == 1)
        {
            return(0);
        }

        var queue = new OrderedBag <State>((pair1, pair2) =>
                                           pair1.Value.CompareTo(pair2.Value)
                                           );

        queue.Add(new State(n, 0));

        while (queue.Count != 0)
        {
            var currentState = queue.RemoveFirst();

            if (currentState.Key == 1)
            {
                return(currentState.Value);
            }

            for (int power = 2; power < 60; power++)
            {
                var powerBase = Math.Pow(currentState.Key, 1.0 / power);

                var nextNumber = (long)Math.Round(powerBase);
                var nextSteps  = Math.Abs(Pow(nextNumber, power) - currentState.Key);

                var nextState = new State(nextNumber, currentState.Value + nextSteps + 1);
                queue.Add(nextState);
            }
        }

        throw new ArgumentException();
    }
예제 #20
0
        static void Main(string[] args)
        {
            int e = int.Parse(Console.ReadLine());

            graph = ReadGraphData(e);
            var startNode = int.Parse(Console.ReadLine());
            var endNode   = int.Parse(Console.ReadLine());
            int maxNode   = graph.Keys.Max();
            var distances = new int[maxNode + 1];
            var prev      = new int[maxNode + 1];

            distances            = distances.Select(x => x = int.MaxValue).ToArray();
            distances[startNode] = 0;
            prev[startNode]      = -1;

            var queue = new OrderedBag <int>
                            (Comparer <int> .Create((x, y) => distances[x] - distances[y]));

            queue.Add(startNode);
            while (queue.Count > 0)
            {
                var node = queue.RemoveFirst();
                if (node == endNode)
                {
                    break;
                }
                var children = graph[node];
                foreach (var child in children)
                {
                    var childNode = child.First == node
                        ? child.Second
                        : child.First;
                    if (distances[childNode] == int.MaxValue)
                    {
                        queue.Add(childNode);
                    }
                    var newDistance = child.Weight + distances[node];
                    if (distances[childNode] > newDistance)
                    {
                        distances[childNode] = newDistance;
                        prev[childNode]      = node;
                        queue = new OrderedBag <int>(queue, Comparer <int>
                                                     .Create((x, y) => distances[x] - distances[y]));
                    }
                }
            }
            if (distances[endNode] == int.MaxValue)
            {
                Console.WriteLine("There is no such path.");
            }
            else
            {
                var path = new Stack <int>();
                path.Push(endNode);
                var current = prev[endNode];
                while (current > -1)
                {
                    path.Push(current);
                    current = prev[current];
                }

                Console.WriteLine(distances[endNode]);
                Console.WriteLine(string.Join(" ", path));
            }
        }
예제 #21
0
        static void Main(string[] args)
        {
            // var queue = new OrderedBag<int>(Comparer<int>.Create((f, s) => s - f));
            var v = int.Parse(Console.ReadLine());
            var e = int.Parse(Console.ReadLine() ?? string.Empty);

            var startEnd = Console.ReadLine().Split().Select(int.Parse).ToArray();
            var start    = startEnd[0];
            var end      = startEnd[1];

            _edgesByNode = ReadGraph(e);

            var maxNode = _edgesByNode.Keys.Max();

            var distances = new int[maxNode + 1];

            for (int i = 0; i < distances.Length; i++) // // Framework C# code
            {
                distances[i] = int.MaxValue;
            }


            distances[start] = 0;

            var prev = new int[maxNode + 1];

            prev[start] = -1;

            var queue = new OrderedBag <int>(
                Comparer <int> .Create((f, s) => distances[f] - distances[s]))
            {
                start
            };

            while (queue.Count > 0)
            {
                var minNode  = queue.RemoveFirst();
                var children = _edgesByNode[minNode];

                if (minNode == end || distances[minNode] == int.MaxValue)
                {
                    break;
                }

                foreach (var child in children)
                {
                    var childNode = child.First == minNode ? child.Second : child.First;

                    if (distances[childNode] == int.MaxValue)
                    {
                        queue.Add(childNode);
                    }

                    var newDistance = child.Weight + distances[minNode];

                    if (newDistance >= distances[childNode])
                    {
                        continue;
                    }
                    distances[childNode] = newDistance;
                    prev[childNode]      = minNode;
                    queue = new OrderedBag <int>(queue, Comparer <int> .Create((f, s) => distances[f] - distances[s]));
                }
            }

            if (distances[end] == int.MaxValue)
            {
                Console.WriteLine("There is no such path.");
                return;
            }



            var path = new Stack <int>();

            var node = end;

            while (node != -1)
            {
                path.Push(node);
                node = prev[node];
            }

            Console.WriteLine(string.Join(" ", path));
            Console.WriteLine(distances[end]);
        }
        static void Main(string[] args)
        {
            // var queue = new OrderedBag<int>(Comparer<int>.Create((f, s) => s - f));
            var v         = int.Parse(Console.ReadLine() ?? string.Empty);
            var exitRooms = Console.ReadLine()
                            .Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries)
                            .Select(int.Parse)
                            .ToArray();
            var e = int.Parse(Console.ReadLine() ?? string.Empty);


            _edgesByNode = ReadGraph(e, v);
            var exitTimeData = Console.ReadLine()
                               .Split(new[] { ":" }, StringSplitOptions.RemoveEmptyEntries)
                               .Select(int.Parse)
                               .ToArray();
            var exitTime = exitTimeData[0] * 60 + exitTimeData[1];



            for (int i = 0; i < v; i++)
            {
                if (exitRooms.Contains(i))
                {
                    continue;
                }

                var distances = new int[v];
                for (int k = 0; k < distances.Length; k++) // // Framework C# code
                {
                    distances[k] = int.MaxValue;
                }

                var start = i;
                distances[start] = 0;

                foreach (var end in exitRooms)
                {
                    var queue = new OrderedBag <int>(
                        Comparer <int> .Create((f, s) => distances[f] - distances[s]))
                    {
                        start
                    };
                    while (queue.Count > 0)
                    {
                        var minNode  = queue.RemoveFirst();
                        var children = _edgesByNode[minNode];

                        if (minNode == end || distances[minNode] == int.MaxValue)
                        {
                            break;
                        }

                        foreach (var child in children)
                        {
                            var childNode = child.First == minNode ? child.Second : child.First;

                            if (distances[childNode] == int.MaxValue)
                            {
                                queue.Add(childNode);
                            }

                            var newDistance = child.Weight + distances[minNode];

                            if (newDistance >= distances[childNode])
                            {
                                continue;
                            }
                            distances[childNode] = newDistance;
                            queue = new OrderedBag <int>(queue,
                                                         Comparer <int> .Create((f, s) => distances[f] - distances[s]));
                        }
                    }
                }

                var quickestWay = exitRooms.Select(t1 => distances[t1]).Concat(new[] { int.MaxValue }).Min();

                if (quickestWay == int.MaxValue)
                {
                    Console.WriteLine($"Unreachable {i} (N/A)");
                    continue;
                }
                var t   = TimeSpan.FromSeconds(quickestWay);
                var sec = string.Format("{0:D2}:{1:D2}:{2:D2}", ((int)t.TotalHours), t.Minutes, t.Seconds);
                Console.WriteLine(quickestWay > exitTime ? $"Unsafe {i} ({sec})" : $"Safe {i} ({sec})");
            }
        }
예제 #23
0
        static void Main()
        {
            /* read input */
            //Dictionary<int, List<Edge>> graph = new Dictionary<int, List<Edge>>();
            //var nodes = int.Parse(Console.ReadLine().Split(' ')[1]);
            //var pathParts = Console.ReadLine().Split(' ');
            //var start = int.Parse(pathParts[1]);
            //var end = int.Parse(pathParts[3]);
            //var edges = int.Parse(Console.ReadLine().Split(' ')[1]);
            //for (int i = 0; i < edges; i++)
            //{
            //    var edgeParts = Console.ReadLine().Split(' ');
            //    var edge = new Edge(int.Parse(edgeParts[0]), int.Parse(edgeParts[1]), int.Parse(edgeParts[2]));
            //    if (!graph.ContainsKey(edge.First))
            //    {
            //        graph[edge.First] = new List<Edge>();
            //    }
            //    if (!graph.ContainsKey(edge.Second))
            //    {
            //        graph[edge.Second] = new List<Edge>();
            //    }

            //    graph[edge.First].Add(edge);
            //    graph[edge.Second].Add(edge);
            //}
            /* end read input */

            //initialize reliabilities array and initially fill all percentagea as min reliability
            percentages = Enumerable.Repeat <double>(-1, graph.Count).ToArray();

            //set reliability of start node (here startNode = 0) to 100% (if stay at start our reliabilitiy will be 100%)
            percentages[start] = 100;

            //initialize visited nodes array
            visited = new bool[graph.Count];

            //mark start node as visited
            visited[start] = true;

            //initialize priority queue and its comparer with sorted rules
            var queue = new OrderedBag <int>(Comparer <int> .Create((a, b) => (int)(percentages[b] - percentages[a])));

            //add start node in priority queue
            queue.Add(start);

            //initialize array to keep nodes to reconstruct path
            var prev = new int[graph.Count];

            prev[start] = -1;

            //while priority queue is not empty
            while (queue.Count > 0)
            {
                //get smallest node
                var min = queue.RemoveFirst();

                //reach node who has not path
                if (percentages[min] == -1)
                {
                    break;
                }

                foreach (var child in graph[min])
                {
                    //get other node of edge (one of them is min)
                    var otherNode = child.First == min ? child.Second : child.First;

                    //mark as visited and add to priority queue
                    if (!visited[otherNode])
                    {
                        visited[otherNode] = true;
                        queue.Add(otherNode);
                    }

                    //precalculate percentage reliability to this node
                    var newPercentage = percentages[min] * child.Reliability / 100;

                    if (newPercentage > percentages[otherNode])
                    {
                        //update reliability
                        percentages[otherNode] = newPercentage;

                        //save prev node
                        prev[otherNode] = min;

                        //sort again priority queue
                        queue = new OrderedBag <int>(queue, Comparer <int> .Create((a, b) => (int)(percentages[b] - percentages[a])));
                    }
                }
            }

            Console.WriteLine($"Most reliable path reliability: {percentages[end]:F2}%");

            //reconstruct path
            var path = new List <int>();
            var curr = end;

            while (curr != -1)
            {
                path.Add(curr);
                curr = prev[curr];
            }

            path.Reverse();

            Console.WriteLine(string.Join(" -> ", path));
        }
예제 #24
0
        public static void Main(string[] args)
        {
            var roomsCount = int.Parse(Console.ReadLine());

            var exitRooms = Console.ReadLine()
                            .Split()
                            .Select(int.Parse)
                            .ToList();

            bestExitTime = new double[roomsCount];
            roomsByExit  = new Dictionary <int, HashSet <int> >();

            for (int room = 0; room < roomsCount; room++)
            {
                if (exitRooms.Contains(room))
                {
                    bestExitTime[room] = 0;
                    roomsByExit[room]  = new HashSet <int>();
                }
                else
                {
                    bestExitTime[room] = double.PositiveInfinity;
                }
            }

            var edgesCount = int.Parse(Console.ReadLine());

            graph = ReadGraph(roomsCount, edgesCount);

            var maxTime = GetTimeInSeconds(Console.ReadLine());

            var queue = new OrderedBag <int>(
                Comparer <int> .Create((f, s) => bestExitTime[f].CompareTo(bestExitTime[s])));

            // Go from each exit into each room
            for (int exitRoomIndex = 0; exitRoomIndex < exitRooms.Count; exitRoomIndex++)
            {
                queue.Add(exitRooms[exitRoomIndex]);

                for (int room = 0; room < roomsCount; room++)
                {
                    while (queue.Count > 0)
                    {
                        var node = queue.RemoveFirst();
                        roomsByExit[exitRooms[exitRoomIndex]].Add(node);

                        if (node == room)
                        {
                            break;
                        }

                        foreach (var edge in graph[node])
                        {
                            var child = edge.First == node
                                ? edge.Second
                                : edge.First;

                            if (double.IsPositiveInfinity(bestExitTime[child]) ||
                                !roomsByExit[exitRooms[exitRoomIndex]].Contains(child))
                            {
                                queue.Add(child);
                            }

                            var newDistance = bestExitTime[node] + edge.TimeInSeconds;

                            if (newDistance < bestExitTime[child])
                            {
                                bestExitTime[child] = newDistance;

                                queue = new OrderedBag <int>(
                                    queue,
                                    Comparer <int> .Create((f, s) => bestExitTime[f].CompareTo(bestExitTime[s])));
                            }
                        }
                    }
                }
            }

            // Print Result
            for (int room = 0; room < bestExitTime.Length; room++)
            {
                if (bestExitTime[room] != 0) // -> if room is not an exit room
                {
                    if (double.IsPositiveInfinity(bestExitTime[room]))
                    {
                        Console.WriteLine($"Unreachable {room} (N/A)");
                    }
                    else if (bestExitTime[room] > maxTime)
                    {
                        Console.WriteLine($"Unsafe {room} ({GetTimeStringFromSeconds((int)bestExitTime[room])})");
                    }
                    else
                    {
                        Console.WriteLine($"Safe {room} ({GetTimeStringFromSeconds((int)bestExitTime[room])})");
                    }
                }
            }
        }
예제 #25
0
        public static long Solve(string[] input)
        {
            var graph = new Dictionary <int, List <CablePath> >();

            foreach (var connection in input)
            {
                var line = connection.Split();
                var from = int.Parse(line[0]);
                var to   = int.Parse(line[1]);
                var cost = int.Parse(line[2]);

                if (!graph.ContainsKey(from))
                {
                    graph.Add(from, new List <CablePath>());
                }

                if (!graph.ContainsKey(to))
                {
                    graph.Add(to, new List <CablePath>());
                }

                graph[from].Add(new CablePath {
                    FromHouse = from, ToHouse = to, Cost = cost
                });
                graph[to].Add(new CablePath {
                    FromHouse = to, ToHouse = from, Cost = cost
                });
            }

            var startNode = graph.First().Key;

            var bag = new OrderedBag <CablePath>();

            foreach (var neighbour in graph[startNode])
            {
                bag.Add(neighbour);
            }

            var minimumSpanningTreeCables = new List <CablePath>();

            var visitedNodes = new HashSet <int>();

            visitedNodes.Add(startNode);

            while (bag.Count > 0)
            {
                var min = bag.RemoveFirst();

                if (visitedNodes.Contains(min.ToHouse))
                {
                    continue;
                }

                minimumSpanningTreeCables.Add(min);

                visitedNodes.Add(min.ToHouse);

                foreach (var neighbour in graph[min.ToHouse])
                {
                    bag.Add(neighbour);
                }
            }

            return(minimumSpanningTreeCables.Sum(c => c.Cost));
        }
예제 #26
0
        static void Main(string[] args)
        {
            var input = Console.ReadLine().Split(' ')
                        .Select(x => int.Parse(x))
                        .ToArray();

            HashSet <int> hospitals = new HashSet <int>(
                Console.ReadLine()
                .Split(' ')
                .Select(x => int.Parse(x)));

            int nodes = input[0]; // points on the map
            int edges = input[1]; // streets

            Dictionary <Node, List <Edge> > graph     = new Dictionary <Node, List <Edge> >();
            Dictionary <int, Node>          nodeNames = new Dictionary <int, Node>();

            for (int i = 0; i < edges; i++)
            {
                var edge = Console.ReadLine().Split(' ')
                           .Select(x => int.Parse(x))
                           .ToArray();
                int fromNode = edge[0];
                int toNode   = edge[1];
                int weight   = edge[2];

                if (!nodeNames.ContainsKey(fromNode))
                {
                    Node node = new Node(fromNode);
                    nodeNames.Add(fromNode, node);
                    graph.Add(node, new List <Edge>());
                }

                if (!nodeNames.ContainsKey(toNode))
                {
                    Node node = new Node(toNode);
                    nodeNames.Add(toNode, node);
                    graph.Add(node, new List <Edge>());
                }

                graph[nodeNames[fromNode]].Add(new Edge(nodeNames[toNode], weight));
                graph[nodeNames[toNode]].Add(new Edge(nodeNames[fromNode], weight)); // Two way streets;
            }

            // for each hospital - dijkstra to each of the houses(not the other hospitals - check for them in the hospitals hashset)
            // Then sum the shortest paths to all the houses and compare with the absolute minimum path
            foreach (var hospital in hospitals)
            {
                foreach (var pair in graph)
                {
                    pair.Key.Path = int.MaxValue;
                }

                var startNode = nodeNames[hospital];
                startNode.Path = 0;

                var queue = new OrderedBag <Node>(); // Will do the work as a priority queue in this case;
                queue.Add(startNode);
                while (queue.Count > 0)
                {
                    var minPathNode = queue.RemoveFirst();
                    if (minPathNode.Path == int.MaxValue)
                    {
                        break;
                    }

                    var minPathNodeEdges = graph[minPathNode];
                    foreach (var edge in minPathNodeEdges)
                    {
                        int path = minPathNode.Path + edge.Weight;
                        if (path < edge.ToNode.Path)
                        {
                            edge.ToNode.Path = path;
                            queue.Add(edge.ToNode);
                        }
                    }
                }

                int currentPath = 0;
                foreach (var pair in nodeNames)
                {
                    if (!hospitals.Contains(pair.Key))
                    {
                        currentPath += pair.Value.Path;
                    }
                }

                if (currentPath < absoluteShortestPath)
                {
                    absoluteShortestPath = currentPath;
                }
            }

            Console.WriteLine(absoluteShortestPath);
        }
예제 #27
0
        static void Main()
        {
            var nmh = Console.ReadLine().Trim().Split().Select(int.Parse).ToArray();

            var hospitalsString = Console.ReadLine().Split();

            var hospitals = new HashSet <int>();

            foreach (var hospStr in hospitalsString)
            {
                hospitals.Add(int.Parse(hospStr));
            }

            var graph = new Dictionary <int, Node>();

            var line = new string[2];
            var from = 0;
            var to   = 0;
            var dist = 0;

            var maxDistance = 99999999;

            for (int i = 0; i < nmh[1]; i++)
            {
                line = Console.ReadLine().Split();
                from = int.Parse(line[0]);
                to   = int.Parse(line[1]);
                dist = int.Parse(line[2]);

                if (!graph.ContainsKey(from))
                {
                    graph.Add(from, new Node(from));
                }

                if (!graph.ContainsKey(to))
                {
                    graph.Add(to, new Node(to));
                }

                graph[from].connections.Add(to, dist);
                graph[to].connections.Add(from, dist);
            }

            long answer = long.MaxValue;

            foreach (var hosp in hospitals)
            {
                var bag = new OrderedBag <Node>();

                foreach (var kv in graph)
                {
                    graph[kv.Key].diikstra = maxDistance;
                    bag.Add(graph[kv.Key]);
                }

                graph[hosp].diikstra = 0;

                while (bag.Count > 0)
                {
                    var min = bag.GetFirst();

                    foreach (var kv in min.connections)
                    {
                        var potDistance = min.diikstra + kv.Value;
                        if (potDistance < graph[kv.Key].diikstra)
                        {
                            graph[kv.Key].diikstra = potDistance;
                            bag.Add(graph[kv.Key]);
                        }
                    }

                    bag.RemoveFirst();
                }

                long currentSum = 0;
                foreach (var kv in graph)
                {
                    if (!hospitals.Contains(kv.Key))
                    {
                        currentSum += graph[kv.Key].diikstra;
                    }
                }

                if (answer > currentSum)
                {
                    answer = currentSum;
                }
            }

            Console.WriteLine(answer);
        }
예제 #28
0
        private static void Diikstra(int startNode)
        {
            var maxKey    = graph.Length;
            var distances = new TimeSpan[maxKey];
            var prev      = new int[maxKey];

            for (int i = 0; i < distances.Length; i++)
            {
                distances[i] = TimeSpan.MaxValue;
            }
            distances[startNode] = new TimeSpan(0, 0, 0);
            var queue = new OrderedBag <int>(Comparer <int> .Create((f, s) => distances[f].CompareTo(distances[s])));
            var end   = -1;

            queue.Add(startNode);

            while (queue.Count > 0)
            {
                var minEdge = queue.RemoveFirst();

                if (exitRooms.Contains(minEdge))
                {
                    end = minEdge;
                    break;
                }

                foreach (var child in graph[minEdge])
                {
                    var actualChild       = minEdge == child.First ? child.Second : child.First;
                    var actualChildWeight = child.Time + distances[minEdge];
                    if (distances[actualChild] == TimeSpan.MaxValue)
                    {
                        queue.Add(actualChild);
                    }

                    if (distances[actualChild] > actualChildWeight)
                    {
                        distances[actualChild] = actualChildWeight;
                        prev[actualChild]      = minEdge;
                        queue = new OrderedBag <int>(queue, Comparer <int> .Create((f, s) => distances[f].CompareTo(distances[s])));
                    }
                }
            }

            if (end != -1)
            {
                var curTime = distances[end];
                if (curTime <= time)
                {
                    Console.WriteLine($"Safe {startNode} ({curTime})");
                }
                else
                {
                    Console.WriteLine($"Unsafe {startNode} ({curTime})");
                }
            }
            else
            {
                Console.WriteLine($"Unreachable {startNode} (N/A)");
            }
        }
예제 #29
0
    private static int Dijkstra(Node[] graphMatrix, int hospital)
    {
        OrderedBag<Connection> streets = new OrderedBag<Connection>();

        Node currentNode = graphMatrix[hospital];
        currentNode.TempDistance = 0;
        currentNode.PermanentDistance = 0;
        currentNode.Visited = true;
        streets.AddMany(currentNode.ChildsList);

        while (streets.Count != 0) // streets.Count == num of streets
        {
            foreach (Connection child in currentNode.ChildsList)
            {
                if (graphMatrix[child.Node].TempDistance >
                    child.Value + currentNode.PermanentDistance)
                {
                    graphMatrix[child.Node].TempDistance =
                        child.Value + currentNode.PermanentDistance;
                }
            }

            int nextNode = streets.RemoveFirst().Node;
            if (graphMatrix[nextNode].Visited == false)
            {
                currentNode = graphMatrix[nextNode];
                streets.AddMany(currentNode.ChildsList);
                currentNode.PermanentDistance = currentNode.TempDistance; currentNode.Visited = true;
            }
        }

        int minDistance = 0;
        for (int i = 1; i < graphMatrix.Length; i++ )
        {
            if (!hospitals.Contains(graphMatrix[i].ID))
            {
                minDistance += graphMatrix[i].PermanentDistance;
            }
        }

        return minDistance;
    }
예제 #30
0
    // Almost the same as Programming/5.DataStructuresAndAlgorithms/AlgoAcademy/4.DataStructures/2.Zadachi/Program.cs
    static void Main()
    {
#if DEBUG
        Console.SetIn(new System.IO.StreamReader("../../input.txt"));
#endif

        var date = DateTime.Now;

        var tasks = new OrderedBag <Tuple <string, int> >((task1, task2) =>
        {
            int compared = 0;

            compared = task1.Item2.CompareTo(task2.Item2);
            if (compared != 0)
            {
                return(compared);
            }

            compared = task1.Item1.CompareTo(task2.Item1);
            if (compared != 0)
            {
                return(compared);
            }

            return(compared);
        });

        var output = new StringBuilder();

        var separator = new char[] { ' ' };

        foreach (int i in Enumerable.Range(0, int.Parse(Console.ReadLine())))
        {
            string line = Console.ReadLine();

            if (line == "Solve")
            {
                if (tasks.Count == 0)
                {
                    output.AppendLine("Rest");
                }

                else
                {
                    output.AppendLine(tasks.RemoveFirst().Item1);
                }
            }

            else
            {
                var match = line.Split(separator, 3);

                tasks.Add(new Tuple <string, int>(match[2], int.Parse(match[1])));
            }
        }

        Console.Write(output);

#if DEBUG
        Console.WriteLine(DateTime.Now - date);
#endif
    }
예제 #31
0
        static void Main(string[] args)
        {
            // var queue = new OrderedBag<int>(Comparer<int>.Create((f, s) => s - f));
            var v     = int.Parse(Console.ReadLine() ?? string.Empty);
            var e     = int.Parse(Console.ReadLine() ?? string.Empty);
            var start = int.Parse(Console.ReadLine() ?? string.Empty);
            var end   = start;

            _edgesByNode = ReadGraph(e, v);
            var maxNode = _edgesByNode.Keys.Max();

            var distances = new double[v];

            for (int i = 0; i < distances.Length; i++) // // Framework C# code
            {
                distances[i] = double.PositiveInfinity;
            }


            distances[start] = 0;

            var prev = new int[v];

            prev[start] = -1;

            // var next = new int[maxNode + 1];
            // for (int i = 0; i < next.Length; i++)
            // {
            //     next[i] = -1;
            // }

            var queue = new OrderedBag <int>(
                Comparer <int> .Create((f, s) => distances[f].CompareTo(distances[s])))
            {
                start
            };
            var begin = true;

            while (queue.Count > 0)
            {
                var minNode  = queue.RemoveFirst();
                var children = _edgesByNode[minNode];

                if ((minNode == end && !begin) || double.IsPositiveInfinity(distances[minNode]))
                {
                    break;
                }

                begin = false;
                foreach (var child in children)
                {
                    var childNode = child.First == minNode ? child.Second : child.First;

                    if (double.IsPositiveInfinity(distances[childNode]))
                    {
                        queue.Add(childNode);
                    }

                    var newDistance = child.Weight + distances[minNode];
                    if (childNode == end && Math.Abs(distances[end]) < 0.01)
                    {
                        distances[end] = double.PositiveInfinity;
                    }

                    if (newDistance >= distances[childNode])
                    {
                        continue;
                    }
                    distances[childNode] = newDistance;
                    prev[childNode]      = minNode;
                    //  next[minNode] = childNode;
                    queue = new OrderedBag <int>(queue, Comparer <int> .Create((f, s) => distances[f].CompareTo(distances[s])));
                }
            }

            Console.WriteLine(Math.Abs(distances[end]) < 0.01
                ? distances.Where(x => !double.IsPositiveInfinity(x)).ToList().Count
                : distances[end]);
        }
예제 #32
0
        static void DijkstraAlgorithm(Dictionary<Node, List<Connection>> graph, Node source)
        {
            OrderedBag<Node> priorQueue = new OrderedBag<Node>();

            foreach (var node in graph)
            {
                node.Key.DijkstraDistance = long.MaxValue;
            }

            source.DijkstraDistance = 0;
            priorQueue.Add(source);

            while (priorQueue.Count != 0)
            {
                Node currentElement = priorQueue.RemoveFirst();

                if (currentElement.DijkstraDistance == long.MaxValue)
                {
                    break;
                }

                foreach (var connection in graph[currentElement])
                {
                    var posDistance = currentElement.DijkstraDistance + connection.Distance;

                    if (posDistance < connection.ToNode.DijkstraDistance)
                    {
                        connection.ToNode.DijkstraDistance = posDistance;
                        priorQueue.Add(connection.ToNode);
                    }
                }
            }

        }
예제 #33
0
 public RasterOp Calculator(Postion startPostion)
 {
     if (!Read(startPostion.XIndex,startPostion.YIndex).HasValue)
         throw new ArgumentOutOfRangeException("起始位置不含有数据");
     RasterPositionValue[,] cost=new RasterPositionValue[Width,Height];
     //初始化操作
     InitializeValues(cost);
     InitializeStart(startPostion,cost);
     //使用orderbag,是的每次取出的最小值
     OrderedBag<RasterPositionValue> bag=new OrderedBag<RasterPositionValue>();
     bag.Add(cost[startPostion.XIndex,startPostion.YIndex]);
     while (bag.Count!=0)
     {
         RasterPositionValue pos = bag.RemoveFirst();
         var postions = Sourround(cost, pos);
         foreach (var postion in postions)
         {
             double relativeCost = Read(postion.XIndex, postion.YIndex).GetValueOrDefault() * 0.5 +
                                  Read(postion.XIndex, postion.YIndex).GetValueOrDefault()*0.5;
             if (pos.XIndex!=postion.XIndex&&pos.YIndex!=postion.YIndex)
             {
                 relativeCost *= Math.Sqrt(2);
             }
             cost[postion.XIndex, postion.YIndex].Visited = true;
             cost[postion.XIndex, postion.YIndex].HasValue = true;
             cost[postion.XIndex, postion.YIndex].RasterValue = (float) relativeCost
                 +cost[pos.XIndex,pos.YIndex].RasterValue;
             bag.Add(cost[postion.XIndex, postion.YIndex]);
         }
     }
     return Result(cost);
 }
        static void Main(string[] args)
        {
            var nodesCount = int.Parse(Console.ReadLine());
            var edgesCount = int.Parse(Console.ReadLine());
            var startNode  = int.Parse(Console.ReadLine());

            graph = ReadGraph(nodesCount, edgesCount);

            var distances = new double[nodesCount];

            for (int node = 0; node < distances.Length; node++)
            {
                distances[node] = double.PositiveInfinity;
            }

            var queue = new OrderedBag <int>
                            (Comparer <int> .Create((f, s) => distances[f].CompareTo(distances[s])));

            foreach (var edge in graph[startNode])
            {
                distances[edge.To] = edge.Distance;
                queue.Add(edge.To);
            }

            var visited = new HashSet <int> {
                startNode
            };

            while (queue.Any())
            {
                var node = queue.RemoveFirst();
                visited.Add(node);

                if (node == startNode)
                {
                    break;
                }

                foreach (var edge in graph[node])
                {
                    var child = edge.To;

                    if (double.IsPositiveInfinity(distances[child]))
                    {
                        queue.Add(child);
                    }

                    var newDistance = distances[node] + edge.Distance;
                    if (newDistance < distances[child])
                    {
                        distances[child] = newDistance;

                        queue = new OrderedBag <int>
                                    (queue, Comparer <int> .Create((f, s) => distances[f].CompareTo(distances[s])));
                    }
                }
            }

            if (double.IsPositiveInfinity(distances[startNode]))
            {
                Console.WriteLine(visited.Count);
            }
            else
            {
                Console.WriteLine(distances[startNode]);
            }
        }
예제 #35
0
        public static void Main(string[] args)
        {
            var nodesCount = int.Parse(Console.ReadLine());
            var edgesCount = int.Parse(Console.ReadLine());

            graph   = ReadGraph(nodesCount, edgesCount);
            cameras = ReadCameras(nodesCount);

            var startNode = int.Parse(Console.ReadLine());
            var endNode   = int.Parse(Console.ReadLine());

            var distances = new double[nodesCount];

            for (int i = 0; i < distances.Length; i++)
            {
                distances[i] = double.PositiveInfinity;
            }

            var queue = new OrderedBag <int>(
                Comparer <int> .Create((f, s) => distances[f].CompareTo(distances[s])));

            distances[startNode] = 0;
            queue.Add(startNode);

            while (queue.Count > 0)
            {
                var node = queue.RemoveFirst();

                if (node == endNode)
                {
                    break;
                }

                foreach (var edge in graph[node])
                {
                    var child = edge.First == node
                        ? edge.Second
                        : edge.First;

                    if (cameras[child])
                    {
                        continue;
                    }

                    if (double.IsPositiveInfinity(distances[child]))
                    {
                        queue.Add(child);
                    }

                    var newDistance = distances[node] + edge.Distance;

                    if (newDistance < distances[child])
                    {
                        distances[child] = newDistance;

                        queue = new OrderedBag <int>(
                            queue,
                            Comparer <int> .Create((f, s) => distances[f].CompareTo(distances[s])));
                    }
                }
            }

            Console.WriteLine(distances[endNode]);
        }
예제 #36
0
        //private static void InsertOpenNode(PathNode node)
        //{
        //	for (var i = 0; i < openList.Count; i++)
        //	{
        //		if (node.F < openList[i].F)
        //		{
        //			openList.Insert(i, node);
        //			return;
        //		}
        //	}

        //	openList.Add(node);
        //}

        private static PathNode BuildPath(MapWalkData walkData, Position start, Position target, int maxLength, int range)
        {
            if (nodeCache == null)
            {
                BuildCache();
            }

            cachePos         = MaxCacheSize;
            Pathfinder.range = range;

            //openList.Clear();
            openBag.Clear();
            openListPos.Clear();
            closedListPos.Clear();
            nodeLookup.Clear();

            var current = NextPathNode(null, start, CalcDistance(start, target));

            openBag.Add(current);
            //openList.Add(current);
            AddLookup(start, current);

            while (openBag.Count > 0 && !closedListPos.Contains(target))
            {
                //current = openList[0];
                current = openBag[0];
                openBag.RemoveFirst();
                //openList.RemoveAt(0);
                openListPos.Remove(current.Position);
                closedListPos.Add(current.Position);

                if (current.Steps > maxLength || current.Steps + current.Distance / 2 > maxLength)
                {
                    continue;
                }

                for (var x = -1; x <= 1; x++)
                {
                    for (var y = -1; y <= 1; y++)
                    {
                        if (x == 0 && y == 0)
                        {
                            continue;
                        }

                        var np = current.Position;
                        np.X += x;
                        np.Y += y;

                        if (np.X < 0 || np.Y < 0 || np.X >= walkData.Width || np.Y >= walkData.Height)
                        {
                            continue;
                        }

                        if (openListPos.Contains(np))
                        {
                            //the open list contains the neighboring cell. Check if the path from this node is better or not
                            var oldNode  = GetNode(np);
                            var dir      = (np - current.Position).GetDirectionForOffset();
                            var distance = CalcDistance(np, target);
                            var newF     = current.Score + 1 + distance + (dir.IsDiagonal() ? 0.4f : 0f);
                            if (newF < oldNode.F)
                            {
                                oldNode.Set(current, np, CalcDistance(np, target));                                 //swap the old parent to us if we're better
                            }

                            continue;
                        }

                        if (closedListPos.Contains(np))
                        {
                            continue;
                        }


                        if (!walkData.IsCellWalkable(np))
                        {
                            continue;
                        }

                        if (x == -1 && y == -1)
                        {
                            if (!walkData.IsCellWalkable(current.Position.X - 1, current.Position.Y) ||
                                !walkData.IsCellWalkable(current.Position.X, current.Position.Y - 1))
                            {
                                continue;
                            }
                        }

                        if (x == -1 && y == 1)
                        {
                            if (!walkData.IsCellWalkable(current.Position.X - 1, current.Position.Y) ||
                                !walkData.IsCellWalkable(current.Position.X, current.Position.Y + 1))
                            {
                                continue;
                            }
                        }

                        if (x == 1 && y == -1)
                        {
                            if (!walkData.IsCellWalkable(current.Position.X + 1, current.Position.Y) ||
                                !walkData.IsCellWalkable(current.Position.X, current.Position.Y - 1))
                            {
                                continue;
                            }
                        }

                        if (x == 1 && y == 1)
                        {
                            if (!walkData.IsCellWalkable(current.Position.X + 1, current.Position.Y) ||
                                !walkData.IsCellWalkable(current.Position.X, current.Position.Y + 1))
                            {
                                continue;
                            }
                        }

                        if (np.SquareDistance(target) <= range)
                        {
                            Profiler.Event(ProfilerEvent.PathFoundIndirect);
                            return(NextPathNode(current, np, 0));
                        }

                        var newNode = NextPathNode(current, np, CalcDistance(np, target));
                        //openList.Add(newNode);

                        //InsertOpenNode(newNode);

                        openBag.Add(newNode);
                        //openListPos.Add(np);
                        AddLookup(np, newNode);
                        closedListPos.Add(np);

                        //openList.Sort((a, b) => a.F.CompareTo(b.F));
                    }
                }
            }

            Profiler.Event(ProfilerEvent.PathNotFound);

            return(null);
        }
예제 #37
0
        private void astar(long x, long y)
        {
            double bound = md.n + md.m;
            OrderedBag <KeyValuePair <long, Point> > pq  = new OrderedBag <KeyValuePair <long, Point> >(new cmp());
            OrderedBag <KeyValuePair <long, Point> > pq2 = new OrderedBag <KeyValuePair <long, Point> >(new cmp());

            V2 = new System.Windows.Vector(md.edx - x, md.edy - y);
            V1 = new System.Windows.Vector(1, 0);
            //FastPriorityQueue<node> pq = new FastPriorityQueue<node>(md.n*md.m/10);
            //PriorityQueue pq = new PriorityQueue((IComparer)new cmp());
            pq.Add(new KeyValuePair <long, Point>(G[x, y] + H(new Point((int)x, (int)y)), new Point((int)x, (int)y)));
            //pq.Enqueue(new KeyValuePair<long,Point>(G[x, y] + H(new Point(x, y)), new Point(x, y))));
            G[x, y]   = 1;
            vis[x, y] = true;
            KeyValuePair <long, Point> kvp;

            while (pq.Count != 0)
            {
                if (pq.Count != 0)
                {
                    kvp = pq.RemoveFirst();
                }
                else
                {
                    kvp = pq2.RemoveFirst();
                }
                x = kvp.Value.X;
                y = kvp.Value.Y;
                md.Que.Enqueue(new DrawTask((int)x * md.pW, (int)y * md.pH, md.pW, md.pH, Color.Green));
                Thread.Sleep(md.delay);
                for (long i = 0; i < 4; i++)
                {
                    long g   = x + dir[i, 0];
                    long h   = y + dir[i, 1];
                    long now = kvp.Key;

                    if (g >= 0 && h >= 0 && g < md.n && h < md.m)
                    {
                        if (!vis[g, h] && md.myMaze.maze[g, h] == 0)
                        {
                            G[g, h] = G[x, y] + 1;
                            if (g == md.edx && h == md.edy)
                            {
                                parent[g, h] = new KeyValuePair <long, long>(x, y);
                                md.Que.Enqueue(new DrawTask((int)x * md.pW, (int)y * md.pH, md.pW, md.pH, Color.Green));
                                Thread.Sleep(md.delay);
                                markPath((int)g, (int)h);
                                return;
                            }
                            V1 = new System.Windows.Vector(g - x, h - y);
                            V2 = new System.Windows.Vector(md.edx - x, md.edy - y);
                            long here = G[g, h] + H(new Point((int)g, (int)h));
                            vis[g, h]    = true;
                            parent[g, h] = new KeyValuePair <long, long>(x, y);
                            pq.Add(new KeyValuePair <long, Point>(here, new Point((int)g, (int)h)));
                            if (pq.Count > bound)
                            {
                                pq2.Add(pq.RemoveLast());
                            }
                        }
                    }
                }
            }
        }
        private static void GetShortestPath(Dictionary <int, List <Edge> > graph, int start, HashSet <int> exits, TimeSpan evacuateTime)
        {
            TimeSpan[] distances = new TimeSpan[graph.Count];
            for (int i = 0; i < distances.Length; i++)
            {
                distances[i] = TimeSpan.MaxValue;
            }
            distances[start] = TimeSpan.Zero;

            int[] previous = new int[graph.Count];
            previous[start] = -1;

            OrderedBag <int> queue = new OrderedBag <int>(
                Comparer <int> .Create((a, b) => distances[a].CompareTo(distances[b])));

            queue.Add(start);

            bool isReachable = false;

            while (queue.Count > 0)
            {
                int node = queue.RemoveFirst();

                if (exits.Contains(node))
                {
                    TimeSpan neededTime = distances[node];
                    string   saveUnsave = neededTime <= evacuateTime ? "Safe" : "Unsafe";

                    Console.WriteLine($"{saveUnsave} {start} ({neededTime})");

                    isReachable = true;

                    break;
                }

                foreach (Edge edge in graph[node])
                {
                    int childNode = edge.Second;

                    if (distances[childNode] == TimeSpan.MaxValue)
                    {
                        queue.Add(childNode);
                    }

                    TimeSpan newDistance = edge.Time + distances[node];

                    if (newDistance < distances[childNode])
                    {
                        distances[childNode] = newDistance;
                        previous[childNode]  = node;

                        queue = new OrderedBag <int>(
                            queue,
                            Comparer <int> .Create((a, b) => distances[a].CompareTo(distances[b])));
                    }
                }
            }

            if (!isReachable)
            {
                Console.WriteLine($"Unreachable {start} (N/A)");
            }
        }
예제 #39
0
    public T Dequeue()
    {
        T element = queue.RemoveFirst();

        return(element);
    }
        private void ComputeNextActions()
        {
            float goalDestinationX = player.Location.X + 983;
            HashSet<int> visited = new HashSet<int>();

            orderedSet = new OrderedBag<PlayerNode>((a, b) => a.Destination((int)goalDestinationX).CompareTo(b.Destination((int)goalDestinationX)));

            PlayerNode initialNode = new PlayerNode(null, sceneTime, 0, PlayerAction.None, player.Clone(), 0);
            orderedSet.Add(initialNode);
            visited.Add((int)initialNode.PlayerElement.Location.X << 10 + (int)initialNode.PlayerElement.Location.Y);

            PlayerNode bestNode = initialNode;
            bool foundBest = false;

            while (orderedSet.Count > 0 && !foundBest)
            {
                PlayerNode current = orderedSet.RemoveFirst();

                if (current.PlayerElement.IsOnGround() && bestNode.Destination((int)goalDestinationX) > current.Destination((int)goalDestinationX))
                {
                    bestNode = current;
                }

                foreach (PlayerAction action in possibleActions)
                {
                    if (action == PlayerAction.Jump && !current.PlayerElement.IsOnGround())
                    {
                        continue;
                    }

                    PlayerElement newPlayer = current.PlayerElement.Clone();
                    newPlayer.IsPlayerAGoat = true;
                    switch (action)
                    {
                        case PlayerAction.None:
                            newPlayer.Stop();
                            break;
                        case PlayerAction.MoveRight:
                            newPlayer.MoveForward();
                            break;
                        case PlayerAction.MoveLeft:
                            newPlayer.MoveBackward();
                            break;
                        case PlayerAction.Jump:
                            newPlayer.Jump();
                            break;
                    }

                    GameTime newTime = IncrementTime(current.Time);
                    newPlayer.Update(newTime);
                    Parallel.ForEach(timeDependentElements, element => element.Update(newTime));
                    HandleInteraction(newPlayer);
                    if (newPlayer.IsDead)
                    {
                        continue;
                    }

                    int hash = ((int)(newPlayer.Location.X * 10) << 7) + (int)newPlayer.Location.Y;
                    if (!visited.Add(hash))
                    {
                        continue;
                    }

                    PlayerNode newNode = new PlayerNode(current, newTime, current.Moves + 1, action, newPlayer, current.Jumps + (action == PlayerAction.Jump ? 1 : 0));
                    if (newPlayer.Location.X > goalDestinationX && newPlayer.IsOnGround() || newPlayer.HasWon)
                    {
                        bestNode = newNode;
                        foundBest = true;
                        break;
                    }
                    orderedSet.Add(newNode);
                }
            }

            orderedSet.Clear();
            if (bestNode == initialNode)
            {
                pendingActions.Enqueue(PlayerAction.None);
            }
            else
            {
                GetActionsFromNode(bestNode);
            }
        }
예제 #41
0
    public static void Main()
    {
        int lineCount = int.Parse((Console.ReadLine().Split()[1]));

        var hospitals = new HashSet <int>(Console.ReadLine().Split().Select(int.Parse));

        var allNodes = new Dictionary <int, Node>();

        for (int i = 0; i < lineCount; i++)
        {
            var line = Console.ReadLine().Split().Select(int.Parse).ToArray();

            if (!allNodes.ContainsKey(line[0]))
            {
                allNodes.Add(line[0], new Node(line[0]));
            }

            if (!allNodes.ContainsKey(line[1]))
            {
                allNodes.Add(line[1], new Node(line[1]));
            }

            allNodes[line[0]].Connections.Add(new Connection(allNodes[line[1]], line[2]));
            allNodes[line[1]].Connections.Add(new Connection(allNodes[line[0]], line[2]));
        }

        foreach (var hos in hospitals)
        {
            allNodes[hos].IsHospital = true;
        }

        long answer = long.MaxValue;

        foreach (var hosp in hospitals)
        {
            OrderedBag <Node> unvisited = new OrderedBag <Node>();
            foreach (var node in allNodes)
            {
                if (node.Key == hosp)
                {
                    continue;
                }
                node.Value.Djikstra = int.MaxValue;
                unvisited.Add(node.Value);
            }

            allNodes[hosp].Djikstra = 0;
            unvisited.Add(allNodes[hosp]);

            while (unvisited.Count != 0)
            {
                var currNode = unvisited.GetFirst();

                unvisited.RemoveFirst();

                foreach (var con in currNode.Connections)
                {
                    var potential = currNode.Djikstra + con.Weight;

                    if (potential < con.ToNodeID.Djikstra)
                    {
                        con.ToNodeID.Djikstra = potential;
                        unvisited.Add(con.ToNodeID);
                    }
                }
            }

            long curr = allNodes.Sum(x => x.Value.Djikstra);

            foreach (var hos in hospitals)
            {
                curr -= allNodes[hos].Djikstra;
            }

            if (answer > curr)
            {
                answer = curr;
            }
        }

        Console.WriteLine(answer);
    }
예제 #42
0
파일: Map.cs 프로젝트: alex-fomin/Game
        public Stack <Point> GetEasiestWay(Point start, Point dest)
        {
            var resultStack = new Stack <Point>();

            resultStack.Push(dest);

            var workPoints      = new OrderedBag <WayPoint>();
            var processedPoints = new Dictionary <Point, WayPoint>();

            var startP = PointToCell(start);
            var destP  = PointToCell(dest);

            if (startP.Equals(destP))
            {
                return(resultStack);
            }

            var totdistX  = Math.Abs(destP.X - startP.X);
            var totdistY  = Math.Abs(destP.Y - startP.Y);
            var startWayP = new WayPoint(null, startP, 0, (totdistX > totdistY ? totdistY * 14 + 10 * (totdistX - totdistY) : totdistX * 14 + 10 * (totdistY - totdistX)));

            workPoints.Add(startWayP);
            processedPoints.Add(startWayP.Point, startWayP);
            WayPoint current = null;

            while (workPoints.Count > 0 /*&& !destP.Equals( workPoints.First().Point ) */)
            {
                current = workPoints.RemoveFirst();
                if (destP.Equals(current.Point))
                {
                    break;
                }

                for (var dx = -1; dx <= 1; dx++)
                {
                    for (var dy = -1; dy <= 1; dy++)
                    {
                        if (dx == 0 && dy == 0)
                        {
                            continue;
                        }

                        var temp = new Point
                        {
                            X = current.Point.X + dx,
                            Y = current.Point.Y + dy
                        };


                        if (temp.X < 0 || temp.X >= _map.GetLength(0))
                        {
                            continue;
                        }

                        if (temp.Y < 0 || temp.Y >= _map.GetLength(1))
                        {
                            continue;
                        }

                        if (GetHObjectFromCellXy(temp.X, temp.Y) != null && !GetHObjectFromCellXy(temp.X, temp.Y).IsPassable &&
                            !destP.Equals(temp))
                        {
                            continue;
                        }

                        var tmpCost = (((dx + dy) % 2 == 0) ? 14 : 10) + current.Cost;
                        // если обрабатываемая клетка лежит по диагонали к родительской - прибавляем 14(приближ. корень2), если нет - 10

                        if (processedPoints.ContainsKey(temp))
                        {
                            if (processedPoints[temp].IsProcessed)
                            {
                                continue;
                            }

                            if (tmpCost < processedPoints[temp].Cost)
                            {
                                processedPoints[temp].Cost   = tmpCost;
                                processedPoints[temp].Parent = current;
                            }
                        }
                        else
                        {
                            var distX       = Math.Abs(destP.X - temp.X);
                            var distY       = Math.Abs(destP.Y - temp.Y);
                            var tmpEvristic =
                                distX > distY ? distY * 14 + 10 * (distX - distY) : distX * 14 + 10 * (distY - distX);
                            var next = new WayPoint(current, temp, tmpCost, tmpEvristic);

                            workPoints.Add(next);
                            processedPoints.Add(next.Point, next);
                        }
                    }
                }

                current.IsProcessed = true;
            }

            if (workPoints.Count == 0)
            {
                resultStack.Clear();
                //  current = processedPoints.Values.Min()
                //  current = processedPoints.Values.OrderBy( waypoint => waypoint.Evristic).First();
            }


            //  if( workPoints.Count > 0 )
            //  {

            current = current?.Parent;
            while (current != null)
            {
                var stackPoint = new Point(current.Point.X * CellMeasure + CellMeasure / 2, current.Point.Y * CellMeasure + CellMeasure / 2);

                if (!current.Point.Equals(destP) || GetHObjectFromCellXy(destP.X, destP.Y) == null || GetHObjectFromCellXy(destP.X, destP.Y).IsPassable)
                {
                    resultStack.Push(stackPoint);
                }

                current = current.Parent;
            }
            //  }

            return(resultStack);
        }
예제 #43
0
        static void Main()
        {
            int nodesCount = int.Parse(Console.ReadLine().Split(' ')[1]);

            string[] pathTokens = Console.ReadLine().Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
            int      startNode  = int.Parse(pathTokens[1]);
            int      endNode    = int.Parse(pathTokens[3]);

            int edgesCount = int.Parse(Console.ReadLine().Split(' ')[1]);

            graph = new Dictionary <int, List <Edge> >();

            ReadGraph(edgesCount);

            percentages            = Enumerable.Repeat <double>(-1, graph.Count).ToArray();
            percentages[startNode] = 100;

            bool[] visited = new bool[graph.Count];
            visited[startNode] = true;

            previous            = new int[graph.Count];
            previous[startNode] = -1;

            //Djikstra's algorithm

            var queue = new OrderedBag <int>(Comparer <int> .Create((a, b) => (int)(percentages[b] - percentages[a])));

            queue.Add(startNode);

            while (queue.Any())
            {
                int nodeWithMaxPercentage = queue.RemoveFirst();

                if (percentages[nodeWithMaxPercentage] == -1)
                {
                    break; //reached a node with no path further
                }

                foreach (Edge edge in graph[nodeWithMaxPercentage])
                {
                    var otherNode = edge.FirstNode == nodeWithMaxPercentage
                        ? edge.SecondNode
                        : edge.FirstNode;

                    if (!visited[otherNode])
                    {
                        visited[otherNode] = true;
                        queue.Add(otherNode);
                    }

                    double newPercentage = percentages[nodeWithMaxPercentage] / 100 * edge.Cost;

                    if (percentages[otherNode] < newPercentage)
                    {
                        percentages[otherNode] = newPercentage;
                        previous[otherNode]    = nodeWithMaxPercentage;

                        //have yo sort again because percentages has changed
                        queue = new OrderedBag <int>(
                            queue,
                            Comparer <int> .Create((a, b) => (int)(percentages[b] - percentages[a])));
                    }
                }
            }

            PrintMostReliablePath(endNode);
        }
    public T Dequeue()
    {
        T element = m_multiset.RemoveFirst();

        return(element);
    }
예제 #45
0
        public override ReadOnlyCollection <Connection> FindPath(Region source_, Region dest_)
        {
            OrderedBag <Pathfinder.PathNode> orderedBag1 = new OrderedBag <Pathfinder.PathNode>((IComparer <Pathfinder.PathNode>) new AStar.NodeComparer());
            OrderedBag <Pathfinder.PathNode> orderedBag2 = new OrderedBag <Pathfinder.PathNode>((IComparer <Pathfinder.PathNode>) new AStar.NodeComparer());

            Pathfinder.PathNode pathNode1 = new Pathfinder.PathNode();
            DateTime            now       = DateTime.Now;

            pathNode1.ConnectCost   = 0.0f;
            pathNode1.EstimatedCost = 0.0f;
            pathNode1.TotalCost     = 0.0f;
            pathNode1.RegionRef     = source_;
            pathNode1.Parent        = (Pathfinder.PathNode)null;
            pathNode1.CurrentLink   = (Connection)null;
            orderedBag1.Add(pathNode1);
            while (orderedBag1.Count != 0)
            {
                Pathfinder.PathNode pathNode2 = orderedBag1.RemoveFirst();
                if (pathNode2.RegionRef == dest_)
                {
                    Pathfinder.PathNode pathNode3      = pathNode2;
                    List <Connection>   connectionList = new List <Connection>();
                    for (; pathNode3.Parent != null; pathNode3 = pathNode3.Parent)
                    {
                        connectionList.Add(pathNode3.CurrentLink);
                    }
                    connectionList.Reverse();
                    TimeSpan timeSpan = DateTime.Now - now;
                    AStar.s_log.Debug("PathFind finishTime: " + (object)timeSpan.TotalMilliseconds);
                    return(new ReadOnlyCollection <Connection>((IList <Connection>)connectionList));
                }
                int count1 = pathNode2.RegionRef.Connections.Count;
                for (int index1 = 0; index1 < count1; ++index1)
                {
                    Connection connection = pathNode2.RegionRef.Connections[index1];
                    bool       flag       = false;
                    int        count2     = orderedBag1.Count;
                    for (int index2 = 0; index2 < count2; ++index2)
                    {
                        Pathfinder.PathNode pathNode3 = orderedBag1[index2];
                        if (pathNode3.RegionRef == connection.To)
                        {
                            if ((double)pathNode2.ConnectCost + (double)connection.Distance < (double)pathNode3.ConnectCost)
                            {
                                pathNode3.ConnectCost = pathNode2.ConnectCost + connection.Distance;
                                pathNode3.TotalCost   = pathNode3.ConnectCost + pathNode3.EstimatedCost;
                                pathNode3.Parent      = pathNode2;
                                pathNode3.CurrentLink = connection;
                                orderedBag1.Remove(pathNode3);
                                orderedBag1.Add(pathNode3);
                            }
                            flag = true;
                            break;
                        }
                    }
                    if (!flag)
                    {
                        int count3 = orderedBag2.Count;
                        for (int index2 = 0; index2 < count3; ++index2)
                        {
                            if (orderedBag2[index2].RegionRef == connection.To)
                            {
                                flag = true;
                                break;
                            }
                        }
                    }
                    if (!flag)
                    {
                        Pathfinder.PathNode pathNode3 = new Pathfinder.PathNode();
                        pathNode3.Parent        = pathNode2;
                        pathNode3.RegionRef     = connection.To;
                        pathNode3.ConnectCost   = pathNode2.ConnectCost + connection.Distance;
                        pathNode3.EstimatedCost = this.Heuristic(pathNode2.RegionRef, dest_);
                        pathNode3.TotalCost     = pathNode3.ConnectCost + pathNode3.EstimatedCost;
                        pathNode3.CurrentLink   = connection;
                        orderedBag1.Add(pathNode3);
                    }
                }
                orderedBag2.Add(pathNode2);
            }
            TimeSpan timeSpan1 = DateTime.Now - now;

            AStar.s_log.Debug("PathFind failed finishTime: " + (object)timeSpan1.TotalMilliseconds);
            return((ReadOnlyCollection <Connection>)null);
        }
예제 #46
0
        static void Main()
        {
            var nodeCunt  = int.Parse(Console.ReadLine().Split()[1]);
            var pathData  = Console.ReadLine().Split();
            var start     = int.Parse(pathData[1]);
            var end       = int.Parse(pathData[3]);
            var edgeCount = int.Parse(Console.ReadLine().Split()[1]);

            graph = new Dictionary <int, List <Edge> >();

            for (int i = 0; i < edgeCount; i++)
            {
                var input = Console.ReadLine()
                            .Split()
                            .Select(int.Parse)
                            .ToArray();
                var edge = new Edge
                {
                    First  = input[0],
                    Second = input[1],
                    Cost   = input[2]
                };

                if (!graph.ContainsKey(edge.First))
                {
                    graph[edge.First] = new List <Edge>();
                }

                if (!graph.ContainsKey(edge.Second))
                {
                    graph[edge.Second] = new List <Edge>();
                }

                graph[edge.First].Add(edge);
                graph[edge.Second].Add(edge);
            }

            visited        = new bool[graph.Count];
            visited[start] = true;

            prev        = new int[graph.Count];
            prev[start] = -1;

            percentages        = Enumerable.Repeat <double>(-1, graph.Count).ToArray();
            percentages[start] = 100;

            var queue = new OrderedBag <int>(
                Comparer <int> .Create((a, b) => (int)(percentages[b] - percentages[a])));

            queue.Add(start);

            while (queue.Count > 0)
            {
                var min = queue.RemoveFirst();
                if (percentages[min] == -1)
                {
                    break;
                }

                foreach (var child in graph[min])
                {
                    var otherNode = child.First == min
                        ? child.Second
                        : child.First;

                    if (!visited[otherNode])
                    {
                        visited[otherNode] = true;
                        queue.Add(otherNode);
                    }

                    var newPerc = percentages[min] / 100 * child.Cost;

                    if (percentages[otherNode] < newPerc)
                    {
                        percentages[otherNode] = newPerc;

                        prev[otherNode] = min;

                        queue = new OrderedBag <int>(
                            queue,
                            Comparer <int> .Create((a, b) => (int)(percentages[b] - percentages[a])));
                    }
                }
            }

            var result  = new List <int>();
            var current = end;

            while (current != -1)
            {
                result.Add(current);
                current = prev[current];
            }
            result.Reverse();
            Console.WriteLine($"Most reliable path reliability: {percentages[end]:F2}%");
            Console.WriteLine(string.Join(" -> ", result));
        }
예제 #47
0
 public NodeModelModel Pop()
 {
     return(priorityQueue.RemoveFirst());
 }