Advertisement
habur331

Untitled

Apr 22nd, 2022
1,134
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 18.60 KB | None | 0 0
  1. import java.util.*;
  2.  
  3. public class Main
  4. {
  5.  
  6.     public static void main(String[] args)
  7.     {
  8.         UndirectedAdjacencyMatrixGraph<PriorityQueueNode<Double, VertexDate>, EdgeDate> graph = new UndirectedAdjacencyMatrixGraph<>(10000);
  9.         HashMap<String, Graph<PriorityQueueNode<Double, VertexDate>, EdgeDate>.Vertex> verticesMap = new HashMap<>();
  10.  
  11.         try (Scanner in = new Scanner(System.in))
  12.         {
  13.             int n = in.nextInt();
  14.             int j = 0;
  15.  
  16.             for (int i = 0; i < n; i++)
  17.             {
  18.                 String command = in.next();
  19.  
  20.                 if (command.equals("ADD"))
  21.                 {
  22.                     String vertexName = in.next();
  23.                     Double vertexPenalty = in.nextDouble();
  24.                     PriorityQueueNode<Double, VertexDate> newVertex = new PriorityQueueNode<>(Double.MAX_VALUE, new VertexDate(vertexName, vertexPenalty, j++));
  25.  
  26.                     verticesMap.put(vertexName, graph.insertVertex(newVertex));
  27.                 }
  28.                 else if (command.equals("CONNECT"))
  29.                 {
  30.                     Graph<PriorityQueueNode<Double, VertexDate>, EdgeDate>.Vertex u = verticesMap.get(in.next());
  31.                     Graph<PriorityQueueNode<Double, VertexDate>, EdgeDate>.Vertex v = verticesMap.get(in.next());
  32.                     Double cost = in.nextDouble() / (u.data.value.penalty + v.data.value.penalty);
  33.  
  34.                     graph.insertEdge(u, v, new EdgeDate(cost));
  35.                 }
  36.                 else if (command.equals("PRINT_MIN"))
  37.                 {
  38.                     PrimAlgorithm prim = new PrimAlgorithm();
  39.                     printMSTPath(prim.applyAlgorithm(graph));
  40.                 }
  41.             }
  42.         }
  43.         catch (Exception e)
  44.         {
  45.             e.printStackTrace();
  46.         }
  47.     }
  48.  
  49.     private static void printMSTPath(List<Graph<PriorityQueueNode<Double, VertexDate>, EdgeDate>.Edge> list)
  50.     {
  51.         StringBuilder sb = new StringBuilder();
  52.         for(Graph<PriorityQueueNode<Double, VertexDate>, EdgeDate>.Edge edge : list)
  53.         {
  54.             sb.append(edge.endPoint1.data.value.name).append(":").append(edge.endPoint2.data.value.name).append(" ");
  55.         }
  56.         System.out.println(sb);
  57.     }
  58. }
  59.  
  60. class PrimAlgorithm
  61. {
  62.     private final MinPriorityQueue<Double, VertexDate> queue;
  63.     private final HashMap<Graph<PriorityQueueNode<Double, VertexDate>, EdgeDate>.Vertex, Graph<PriorityQueueNode<Double, VertexDate>, EdgeDate>.Edge> vertexEdgeMap;
  64.  
  65.     public PrimAlgorithm()
  66.     {
  67.         vertexEdgeMap = new HashMap<>();
  68.         this.queue = new MinPriorityQueue<>();
  69.     }
  70.  
  71.     public List<Graph<PriorityQueueNode<Double, VertexDate>, EdgeDate>.Edge> applyAlgorithm(UndirectedAdjacencyMatrixGraph<PriorityQueueNode<Double, VertexDate>, EdgeDate> graph) throws Exception
  72.     {
  73.         //List for inserting in queue
  74.         List<PriorityQueueNode<Double, VertexDate>> vertexList = new ArrayList<>(graph.vertices.size());
  75.         for (Graph<PriorityQueueNode<Double, VertexDate>, EdgeDate>.Vertex ver : graph.vertices)
  76.         {
  77.             //I reassign this value because if it not the first applying of algorithm it wil be different from default value
  78.             ver.data.key = Double.MAX_VALUE;
  79.             vertexList.add(ver.data);
  80.         }
  81.  
  82.  
  83.         queue.union(vertexList);
  84.  
  85.         List<Graph<PriorityQueueNode<Double, VertexDate>, EdgeDate>.Edge> ans = new ArrayList<>();
  86.  
  87.         while (queue.size != 0)
  88.         {
  89.             //Достаем элемент с наименьшим расстоянием
  90.             PriorityQueueNode<Double, VertexDate> startVertex = queue.extractMin();
  91.  
  92.             //Adding a new edge to the answer
  93.             if (vertexEdgeMap.get(graph.vertices.get(startVertex.value.positionInGraphList)) != null)
  94.                 ans.add(vertexEdgeMap.get(graph.vertices.get(startVertex.value.positionInGraphList)));
  95.  
  96.             List<Pair<Graph<PriorityQueueNode<Double, VertexDate>, EdgeDate>.Vertex, Graph<PriorityQueueNode<Double, VertexDate>, EdgeDate>.Edge>> adjacentVertices = graph.getAdjacentVertices(graph.vertices.get(startVertex.value.positionInGraphList));
  97.  
  98.             for (Pair<Graph<PriorityQueueNode<Double, VertexDate>, EdgeDate>.Vertex, Graph<PriorityQueueNode<Double, VertexDate>, EdgeDate>.Edge> adjacentVertex : adjacentVertices)
  99.             {
  100.                 Graph<PriorityQueueNode<Double, VertexDate>, EdgeDate>.Edge connectingEdge = graph.getEdge(graph.vertices.get(startVertex.value.positionInGraphList), adjacentVertex.getFirst());
  101.                 Double minCost = queue.get(adjacentVertex.getFirst().data.positionInQueueList).key;
  102.  
  103.                 //Рассматриваем только те вершины, которые находятся в куче
  104.                 if (minCost != null)
  105.                 {
  106.                     if (connectingEdge.data.cost.compareTo(minCost) < 0)
  107.                     {
  108.                         //Transforming adjacentVertex to node of priority queue
  109.                         PriorityQueueNode<Double, VertexDate> consideringNode = adjacentVertex.getFirst().data;
  110.                         queue.decreaseKey(consideringNode, connectingEdge.data.cost);
  111.                         vertexEdgeMap.put(adjacentVertex.getFirst(), connectingEdge);
  112.                     }
  113.                 }
  114.  
  115.             }
  116.         }
  117.  
  118.         return ans;
  119.     }
  120. }
  121.  
  122. class UndirectedAdjacencyMatrixGraph<V, E> extends Graph<V, E>
  123. {
  124.     private final int capacityOfMatrix;
  125.     ArrayList<ArrayList<Graph<V, E>.Edge>> adjacencyMatrix;
  126.  
  127.     public UndirectedAdjacencyMatrixGraph(int initialCapacityOfAdjacencyMatrix)
  128.     {
  129.         vertices = new ArrayList<>();
  130.         edges = new ArrayList<>();
  131.         capacityOfMatrix = initialCapacityOfAdjacencyMatrix;
  132.         adjacencyMatrix = new ArrayList<>(initialCapacityOfAdjacencyMatrix);
  133.     }
  134.  
  135.     @Override
  136.     public Graph<V, E>.Vertex insertVertex(V v)
  137.     {
  138.         Vertex newVertex = new Vertex(v, vertices.size());
  139.         vertices.add(newVertex);
  140.         return newVertex;
  141.     }
  142.  
  143.     @Override
  144.     public Graph<V, E>.Edge insertEdge(Vertex u, Vertex v, E w)
  145.     {
  146.         Edge newEdge = new Edge(u, v, w, edges.size());
  147.         edges.add(newEdge);
  148.  
  149.         if (u.positionInGraphList >= adjacencyMatrix.size())
  150.         {
  151.             int n = u.positionInGraphList - adjacencyMatrix.size();
  152.             for (int i = 0; i < n + 1; i++)
  153.                 adjacencyMatrix.add(new ArrayList<>(capacityOfMatrix));
  154.         }
  155.  
  156.         if (v.positionInGraphList >= adjacencyMatrix.size())
  157.         {
  158.             int n = v.positionInGraphList - adjacencyMatrix.size();
  159.             for (int i = 0; i < n + 1; i++)
  160.                 adjacencyMatrix.add(new ArrayList<>(capacityOfMatrix));
  161.         }
  162.  
  163.         if (v.positionInGraphList >= adjacencyMatrix.get(u.positionInGraphList).size())
  164.         {
  165.             int n = v.positionInGraphList - adjacencyMatrix.get(u.positionInGraphList).size();
  166.             for (int i = 0; i <= n; i++)
  167.                 adjacencyMatrix.get(u.positionInGraphList).add(null);
  168.         }
  169.  
  170.         adjacencyMatrix.get(u.positionInGraphList).set(v.positionInGraphList, newEdge);
  171.  
  172.         if (u.positionInGraphList >= adjacencyMatrix.get(v.positionInGraphList).size())
  173.         {
  174.             int n = u.positionInGraphList - adjacencyMatrix.get(v.positionInGraphList).size();
  175.             for (int i = 0; i <= n; i++)
  176.                 adjacencyMatrix.get(v.positionInGraphList).add(null);
  177.         }
  178.  
  179.         adjacencyMatrix.get(v.positionInGraphList).set(u.positionInGraphList, newEdge);
  180.  
  181.         return newEdge;
  182.     }
  183.  
  184.     //TODO Needed to be checked
  185.     @Override
  186.     public List<Pair<Vertex, Edge>> getAdjacentVertices(Vertex vertex)
  187.     {
  188.         if (vertex.positionInGraphList < adjacencyMatrix.size())
  189.         {
  190.             List<Pair<Vertex, Edge>> list = new ArrayList<>();
  191.             for (Edge edge : adjacencyMatrix.get(vertex.positionInGraphList))
  192.             {
  193.                 if (edge != null)
  194.                 {
  195.                     if (!edge.endPoint1.equals(vertex))
  196.                         list.add(new Pair<>(edge.endPoint1, edge));
  197.                     else list.add(new Pair<>(edge.endPoint2, edge));
  198.                 }
  199.             }
  200.             return list;
  201.         }
  202.         return new ArrayList<>();
  203.     }
  204.  
  205.     //TODO
  206.     @Override
  207.     public void removeVertex(Vertex v)
  208.     {
  209.  
  210.     }
  211.  
  212.     //TODO
  213.     @Override
  214.     public void removeEdge(Edge e)
  215.     {
  216.  
  217.     }
  218.  
  219.     //TODO
  220.     @Override
  221.     public boolean areAdjacent(Vertex v, Vertex u)
  222.     {
  223.         return false;
  224.     }
  225.  
  226.     //TODO
  227.     @Override
  228.     public boolean areAdjacent(Edge v, Edge u)
  229.     {
  230.         return false;
  231.     }
  232.  
  233.     //TODO
  234.     @Override
  235.     public int degree(Vertex v)
  236.     {
  237.         return 0;
  238.     }
  239.  
  240.     @Override
  241.     public Graph<V, E>.Edge getEdge(Graph<V, E>.Vertex u, Graph<V, E>.Vertex v)
  242.     {
  243.         if (adjacencyMatrix.size() > v.positionInGraphList)
  244.         {
  245.             if (adjacencyMatrix.get(v.positionInGraphList) != null)
  246.             {
  247.                 if (adjacencyMatrix.get(v.positionInGraphList).size() > u.positionInGraphList)
  248.                     return adjacencyMatrix.get(v.positionInGraphList).get(u.positionInGraphList);
  249.             }
  250.         }
  251.         return null;
  252.     }
  253. }
  254.  
  255. class EdgeDate
  256. {
  257.     public Double cost;
  258.  
  259.     public EdgeDate(Double cost)
  260.     {
  261.         this.cost = cost;
  262.     }
  263.  
  264.     @Override
  265.     public String toString()
  266.     {
  267.         return "EdgeDate{" +
  268.                 "cost=" + cost +
  269.                 '}';
  270.     }
  271. }
  272.  
  273. class VertexDate implements Comparable<VertexDate>
  274. {
  275.     public String name;
  276.     public Double penalty;
  277.     public int positionInGraphList;
  278.  
  279.     public VertexDate(String name, Double penalty, int positionInGraphList)
  280.     {
  281.         this.name = name;
  282.         this.penalty = penalty;
  283.         this.positionInGraphList = positionInGraphList;
  284.     }
  285.  
  286.     @Override
  287.     public int compareTo(VertexDate o)
  288.     {
  289.         return name.compareTo(o.name);
  290.     }
  291.  
  292.     @Override
  293.     public boolean equals(Object obj)
  294.     {
  295.         if (obj instanceof VertexDate)
  296.         {
  297.             return name.equals(((VertexDate) obj).name);
  298.         }
  299.         else return super.equals(obj);
  300.     }
  301.  
  302.     @Override
  303.     public String toString()
  304.     {
  305.         return "VertexDate{" +
  306.                 "name='" + name + '\'' +
  307.                 ", penalty=" + penalty +
  308.                 '}';
  309.     }
  310. }
  311.  
  312. class MinPriorityQueue<Key extends Comparable<Key>, Value extends Comparable<Value>> implements IPriorityQueue<Key, Value>
  313. {
  314.     protected final List<PriorityQueueNode<Key, Value>> list;
  315.     private final int max_size = 100000 + 10;
  316.     protected int size = 0;
  317.  
  318.     public MinPriorityQueue()
  319.     {
  320.         this.list = new ArrayList<>(max_size);
  321.         for (int i = 0; i < max_size; i++)
  322.             list.add(null);
  323.     }
  324.  
  325.     private int getIndexOfParent(int index)
  326.     {
  327.         return (index - 1) / 2;
  328.     }
  329.  
  330.     private int getIndexOfLeftChild(int index)
  331.     {
  332.         return 2 * index + 1;
  333.     }
  334.  
  335.     private int getIndexOfRight(int index)
  336.     {
  337.         return 2 * index + 2;
  338.     }
  339.  
  340.     private void heapify(int index)
  341.     {
  342.         //There are no checks before calling the methods, because the corresponding checks will be called in the methods themselves.
  343.         if (size > index)
  344.         {
  345.             swim(index);
  346.             sink(index);
  347.         }
  348.     }
  349.  
  350.     private void swim(int index)
  351.     {
  352.         while (index != 0 && list.get(index).compareTo(list.get(getIndexOfParent(index))) < 0)
  353.         {
  354.             PriorityQueueNode.swapPositions(list.get(index), list.get(getIndexOfParent(index)));
  355.             Collections.swap(list, index, getIndexOfParent(index));
  356.             index = getIndexOfParent(index);
  357.         }
  358.     }
  359.  
  360.     private void sink(int index)
  361.     {
  362.         for (; ; )
  363.         {
  364.             int l = getIndexOfLeftChild(index);
  365.             int r = getIndexOfRight(index);
  366.  
  367.             int smallest = index;
  368.  
  369.             if (l < size && list.get(l).compareTo(list.get(smallest)) < 0)
  370.             {
  371.                 smallest = l;
  372.             }
  373.  
  374.             if (r < size && list.get(r).compareTo(list.get(smallest)) < 0)
  375.             {
  376.                 smallest = r;
  377.             }
  378.  
  379.             if (smallest != index)
  380.             {
  381.                 PriorityQueueNode.swapPositions(list.get(index), list.get(smallest));
  382.                 Collections.swap(list, index, smallest);
  383.                 index = smallest;
  384.             }
  385.             else break;
  386.         }
  387.     }
  388.  
  389.     @Override
  390.     public void insert(PriorityQueueNode<Key, Value> item) throws Exception
  391.     {
  392.         if (size == max_size)
  393.             throw new Exception("PriorityQueue is full");
  394.  
  395.         //most likely item has an incorrect "position in list"
  396.         item.positionInQueueList = size;
  397.         list.set(item.positionInQueueList, item);
  398.         size++;
  399.  
  400.         heapify(size - 1);
  401.     }
  402.  
  403.     @Override
  404.     public PriorityQueueNode<Key, Value> findMin()
  405.     {
  406.         return list.get(0);
  407.     }
  408.  
  409.     @Override
  410.     public PriorityQueueNode<Key, Value> extractMin() throws Exception
  411.     {
  412.         if (size == 0)
  413.             throw new Exception("Heap is empty");
  414.  
  415.         PriorityQueueNode<Key, Value> min = list.get(0);
  416.  
  417.         delete(list.get(0));
  418.  
  419.         return min;
  420.     }
  421.  
  422.     @Override
  423.     public void decreaseKey(PriorityQueueNode<Key, Value> item, Key newKey)
  424.     {
  425.         if (list.get(item.positionInQueueList).compareTo(item) == 0)
  426.         {
  427.             item.key = newKey;
  428.             heapify(item.positionInQueueList);
  429.         }
  430.     }
  431.  
  432.     @Override
  433.     public void delete(PriorityQueueNode<Key, Value> item)
  434.     {
  435.         size--;
  436.         //If there are elements but root
  437.         if (size != 0)
  438.         {
  439.             int index = item.positionInQueueList;
  440.             //swapping an extracted root and the last element
  441.             Collections.swap(list, item.positionInQueueList, size);
  442.             PriorityQueueNode.swapPositions(list.get(item.positionInQueueList), list.get(size));
  443.             heapify(index);
  444.         }
  445.     }
  446.  
  447.     @Override
  448.     public void union(MinPriorityQueue<Key, Value> anotherQueue)
  449.     {
  450.         union(anotherQueue.list);
  451.     }
  452.  
  453.     //Optimized addition of elements from another list
  454.     @Override
  455.     public void union(List<PriorityQueueNode<Key, Value>> anotherList)
  456.     {
  457.         for (int i = 0; i < anotherList.size(); i++, size++)
  458.             list.set(size, anotherList.get(i));
  459.  
  460.         int indexOfLastNonLeaf = getIndexOfParent(size - 1);
  461.  
  462.         //New items in list have incorrect field "position in list"
  463.         for (int i = size - 1; i >= size - anotherList.size(); i--)
  464.             list.get(i).positionInQueueList = i;
  465.  
  466.         for (int i = indexOfLastNonLeaf; i >= 0; i--)
  467.             heapify(i);
  468.     }
  469.  
  470.     @Override
  471.     public PriorityQueueNode<Key, Value> get(int positionInQueueList)
  472.     {
  473.         return list.get(positionInQueueList);
  474.     }
  475. }
  476.  
  477. class PriorityQueueNode<Key extends Comparable<Key>, Value extends Comparable<Value>> implements Comparable<PriorityQueueNode<Key, Value>>
  478. {
  479.     public Key key;
  480.     public Value value;
  481.     public int positionInQueueList;
  482.  
  483.     public PriorityQueueNode(Key key, Value value)
  484.     {
  485.         this.key = key;
  486.         this.value = value;
  487.         this.positionInQueueList = -1;
  488.     }
  489.  
  490.     @Override
  491.     public String toString()
  492.     {
  493.         return key + "=" + value;
  494.     }
  495.  
  496.     @Override
  497.     public int compareTo(PriorityQueueNode<Key, Value> o)
  498.     {
  499.         int res = this.key.compareTo(o.key);
  500.  
  501.         if (res != 0)
  502.             return res;
  503.         else return this.value.compareTo(o.value);
  504.     }
  505.  
  506.     @Override
  507.     public boolean equals(Object obj)
  508.     {
  509.         if (obj instanceof PriorityQueueNode<?, ?>)
  510.         {
  511.             return this.key.equals(((PriorityQueueNode<?, ?>) obj).key) && this.value.equals(((PriorityQueueNode<?, ?>) obj).value);
  512.         }
  513.         else return super.equals(obj);
  514.     }
  515.  
  516.     public static void swapPositions(PriorityQueueNode<?, ?> a, PriorityQueueNode<?, ?> b)
  517.     {
  518.         int temp = a.positionInQueueList;
  519.         a.positionInQueueList = b.positionInQueueList;
  520.         b.positionInQueueList = temp;
  521.     }
  522. }
  523.  
  524. abstract class Graph<VertexDataType, EdgeDataType>
  525. {
  526.     protected List<Vertex> vertices;
  527.     protected List<Edge> edges;
  528.  
  529.     abstract public Vertex insertVertex(VertexDataType vertexDataType);
  530.  
  531.     abstract public Edge insertEdge(Vertex u, Vertex v, EdgeDataType w);
  532.  
  533.     public abstract List<Pair<Vertex, Edge>> getAdjacentVertices(Vertex vertex);
  534.  
  535.     abstract public void removeVertex(Vertex v);
  536.  
  537.     abstract public void removeEdge(Edge e);
  538.  
  539.     abstract public boolean areAdjacent(Vertex v, Vertex u);
  540.  
  541.     abstract public boolean areAdjacent(Edge v, Edge u);
  542.  
  543.     abstract public int degree(Vertex v);
  544.  
  545.     abstract public Edge getEdge(Vertex u, Vertex v);
  546.  
  547.     class Vertex
  548.     {
  549.         public VertexDataType data;
  550.         public int positionInGraphList;
  551.  
  552.         public Vertex(VertexDataType data, int positionInGraphList)
  553.         {
  554.             this.data = data;
  555.             this.positionInGraphList = positionInGraphList;
  556.         }
  557.     }
  558.  
  559.     class Edge
  560.     {
  561.         public Vertex endPoint1;
  562.         public Vertex endPoint2;
  563.         public EdgeDataType data;
  564.         public int positionInList;
  565.  
  566.         public Edge(Vertex endPoint1, Vertex endPoint2, EdgeDataType data, int positionInList)
  567.         {
  568.             this.endPoint1 = endPoint1;
  569.             this.endPoint2 = endPoint2;
  570.             this.data = data;
  571.             this.positionInList = positionInList;
  572.         }
  573.     }
  574. }
  575.  
  576. class Pair<K, V>
  577. {
  578.     private K first;
  579.  
  580.     public K getFirst()
  581.     {
  582.         return first;
  583.     }
  584.  
  585.     private V second;
  586.  
  587.     public V getSecond()
  588.     {
  589.         return second;
  590.     }
  591.  
  592.     public Pair(K first, V second)
  593.     {
  594.         this.first = first;
  595.         this.second = second;
  596.     }
  597.  
  598.     public String toString()
  599.     {
  600.         return first + "=" + second;
  601.     }
  602. }
  603.  
  604. interface IPriorityQueue<Key extends Comparable<Key>, Value extends Comparable<Value>>
  605. {
  606.     void insert(PriorityQueueNode<Key, Value> item) throws Exception;
  607.  
  608.     PriorityQueueNode<Key, Value> findMin();
  609.  
  610.     PriorityQueueNode<Key, Value> extractMin() throws Exception;
  611.  
  612.     void decreaseKey(PriorityQueueNode<Key, Value> item, Key newKey);
  613.  
  614.     void delete(PriorityQueueNode<Key, Value> item);
  615.  
  616.     void union(MinPriorityQueue<Key, Value> anotherQueue);
  617.  
  618.     void union(List<PriorityQueueNode<Key, Value>> anotherList);
  619.  
  620.     PriorityQueueNode<Key, Value> get(int positionInQueueList);
  621. }
  622.  
  623.  
  624.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement