Advertisement
habur331

Untitled

Apr 22nd, 2022
1,034
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import java.util.*;
  2. import java.util.stream.Collectors;
  3.  
  4. public class Program {
  5.     public static void main(String[] args) {
  6.         try (Scanner in = new Scanner(System.in)) {
  7.             Integer number = Integer.parseInt(in.next());
  8.  
  9.             DynamicGraph<Double> graph = new DynamicGraph<>(number);
  10.             HashMap<String, Node<Vertex<Double>>> mapV = new HashMap<>();
  11.             ArrayList <Edge<Double, Double>> results = null;
  12.  
  13.             for (int i = 0; i < number; i++) {
  14.                 String command = in.next();
  15.                 if (command.equals("ADD")) {
  16.                     String name = in.next();
  17.                     Double penalty = in.nextDouble();
  18.  
  19.                     mapV.put(name, graph.insertVertex(name, penalty));
  20.                 } else if (command.equals("CONNECT")) {
  21.                     String v = in.next();
  22.                     String u = in.next();
  23.                     Double cost = in.nextDouble();
  24.  
  25.                     graph.insertEdge(mapV.get(v), mapV.get(u), cost);
  26.                 } else if (command.equals("PRINT_MIN")) {
  27.  
  28.                     IPriorityQueue<Vertex<Double>, Double> priorityQueue = new BinaryHeap<>();
  29.                     PrimAlgorithm<Double, Double> primAlgorithm = new PrimAlgorithm<Double, Double>(graph, Double.MAX_VALUE);
  30.                     results = primAlgorithm.applyAlgorithm();
  31.                     StringBuilder builder = new StringBuilder();
  32.                     for (int l = 0; l < results.size(); l++) {
  33.                         builder.append(results.get(l).vertexTo.value.name).append(":").append(results.get(l).vertexFrom.value.name).append(" ");
  34.                         System.out.print(builder);
  35.                         builder.setLength(0);
  36.                     }
  37.                     System.out.println();
  38.                 }
  39.             }
  40.         }
  41.     }
  42. }
  43.  
  44. class PrimAlgorithm<V extends Comparable<V>, E extends Comparable<E>> {
  45.     // храним: key - вес минимамального ребра, value - вершина
  46.     IPriorityQueue<E, Vertex<V>> priorityQueue;
  47.     CommonDynamicGraph<V, E> graph;
  48.     // key - вершина, оборнутая в Node(чтобы иметь быстрый доступ в priorityQueue) value - ребро, минимальное по стоимости
  49.     HashMap<Node<Vertex<V>>, Edge<E, V>> visited;
  50.  
  51.     public <K> PrimAlgorithm(CommonDynamicGraph<V, E> graph, E CUSTOM_INF) {
  52.         this.graph = graph;
  53.         this.priorityQueue = new BinaryHeap<>();
  54.         this.visited = new HashMap<>();
  55.  
  56.         //достаём все вершины с графа и помещаем их в priorityQueue с очень большим значением
  57.         ArrayList<Node<Vertex<V>>> list = graph.vertices;
  58.         ArrayList<Pair<E, Node<Vertex<V>>>> list2 = new ArrayList<>();
  59.         for (Node<Vertex<V>> iterator : list)
  60.         {
  61.             list2.add(new Pair<>(CUSTOM_INF, iterator));
  62.         }
  63.         priorityQueue.union(list2);
  64.     }
  65.  
  66.     public ArrayList <Edge<E, V>> applyAlgorithm() {
  67.         //лист из рёбер, дающих MST
  68.         ArrayList<Edge<E, V>> result = new ArrayList<>();
  69.  
  70.         while (priorityQueue.size() != 0) {
  71.             //достаём элемент с наименьшим ребром
  72.             Node<Vertex<V>> startVertex = priorityQueue.extractMin();
  73.             //добавляем его ребро с map в ответ
  74.             if (visited.get(startVertex) != null)
  75.                 result.add(visited.get(startVertex));
  76.  
  77.             //просим у графа все соседние вершины
  78.             ArrayList<Node<Vertex<V>>> adjacentVertexes = graph.getAdjacentVertexes(startVertex);
  79.  
  80.             //итерируемся по ним
  81.             for (int i = 0; i < adjacentVertexes.size(); i++) {
  82.                 Node<Vertex<V>> adjacentVertex = adjacentVertexes.get(i);
  83.  
  84.                 // мы рассматриваем только те соседние вершины, что не находятся в приорити кью (так как у них уже отмечено минимальноу значение)
  85.                 E minEdge = priorityQueue.getKeyByValue(adjacentVertex);
  86.                 if (minEdge != null) {
  87.  
  88.                     // беру ребро между ними
  89.                     Edge<E, V> newEdge = graph.getEdge(adjacentVertex, startVertex);
  90.                     if (newEdge != null) {
  91.                         E newCost = newEdge.cost;
  92.  
  93.                         // если это рёбро весит меньше, чем рёбро, которое соответвует этой вершине в приорити кью
  94.                         if (newCost.compareTo(minEdge) < 0) {
  95.                             // заменеям ключ на  newCost
  96.                             priorityQueue.decreaseKey(adjacentVertex, newCost);
  97.                             visited.put(adjacentVertex, newEdge);
  98.                         }
  99.                     }
  100.                 }
  101.             }
  102.         }
  103.         return result;
  104.     }
  105. }
  106.  
  107.  
  108. class Vertex<V> implements Comparable<Vertex<V>> {
  109.     public String name;
  110.     public V cost;
  111.     public int indexVertex;
  112.  
  113.     public Vertex(String name, V cost, int index) {
  114.         this.name = name;
  115.         this.cost = cost;
  116.         this.indexVertex = index;
  117.     }
  118.  
  119.     @Override
  120.     public int compareTo(Vertex<V> o) {
  121.         return this.name.compareTo(o.name);
  122.     }
  123.  
  124.     @Override
  125.     public String toString() {
  126.         return this.name;
  127.     }
  128. }
  129.  
  130. class Edge<E extends Comparable<E>, V> {
  131.     public E cost;
  132.     public Node<Vertex<V>> vertexFrom;
  133.     public Node<Vertex<V>> vertexTo;
  134.     public int index;
  135.  
  136.     public Edge(E cost, Node<Vertex<V>> vertexFrom, Node<Vertex<V>> vertexTo, int index) {
  137.         this.cost = cost;
  138.         this.vertexFrom = vertexFrom;
  139.         this.vertexTo = vertexTo;
  140.         this.index = index;
  141.     }
  142. }
  143.  
  144. // V - String, E - Integer
  145. class CommonDynamicGraph<V, E extends Comparable<E>> {
  146.  
  147.     int size;
  148.     int n;
  149.  
  150.     ArrayList<ArrayList<Edge<E, V>>> matrix;
  151.     //список всёз вершин
  152.     ArrayList<Node<Vertex<V>>> vertices;
  153.  
  154.     public CommonDynamicGraph(int n) {
  155.         this.n = n;
  156.         size = 0;
  157.         vertices = new ArrayList<>(n);
  158.         matrix = new ArrayList<>(n);
  159.     }
  160.  
  161.     public ArrayList<Node<Vertex<V>>> getAdjacentVertexes(Node<Vertex<V>> v) {
  162.         ArrayList<Node<Vertex<V>>> vertices = new ArrayList<>(n);
  163.         if (matrix.size() > v.value.indexVertex)
  164.             for (int i = 0; i < matrix.get(v.value.indexVertex).size(); i++) {
  165.                 if (matrix.get(v.value.indexVertex).get(i) != null)
  166.                     vertices.add(matrix.get(v.value.indexVertex).get(i).vertexTo);
  167.             }
  168.         return vertices;
  169.     }
  170.  
  171.     public Edge<E, V> getEdge(Node<Vertex<V>> v, Node<Vertex<V>> u) {
  172.         if (matrix.get(v.value.indexVertex) != null)
  173.             return matrix.get(v.value.indexVertex).get(u.value.indexVertex);
  174.         else return null;
  175.     }
  176.  
  177.     public Node<Vertex<V>> insertVertex(String name, V value) {
  178.         Node<Vertex<V>> newVertex = new Node<Vertex<V>>(new Vertex<>(name, value, size), -1);
  179.         size++;
  180.         vertices.add(newVertex);
  181.         return newVertex;
  182.     }
  183.  
  184.     public Edge<E, V> insertEdge(Node<Vertex<V>> from, Node<Vertex<V>> to, E cost) {
  185.         Edge<E, V> edge1 = new Edge<>(cost, from, to, -1);
  186.         Edge<E, V> edge2 = new Edge<>(cost, to, from, -1);
  187.  
  188.         if (matrix.size() <= from.value.indexVertex || matrix.size() <= to.value.indexVertex)
  189.             for (int i = matrix.size(); i <= Integer.max(from.value.indexVertex, to.value.indexVertex); i++)
  190.                 matrix.add(new ArrayList<>(n));
  191.  
  192.         if (from.value.indexVertex >= matrix.get(to.value.indexVertex).size() || to.value.indexVertex >= matrix.get(from.value.indexVertex).size()) {
  193.             for (int i = matrix.size(); i < Integer.max(from.value.indexVertex, to.value.indexVertex); i++)
  194.                 matrix.get(Integer.min(from.value.indexVertex, to.value.indexVertex)).add(null);
  195.         }
  196.  
  197.         matrix.get(from.value.indexVertex).set(to.value.indexVertex, edge1);
  198.         matrix.get(to.value.indexVertex).set(from.value.indexVertex, edge2);
  199.         return edge1;
  200.     }
  201.  
  202.     public void removeVertex(V v) {
  203.  
  204.     }
  205.  
  206.     public void removeEdge(Edge<E, V> e) {
  207.  
  208.     }
  209.  
  210.     public boolean areAdjacent(Edge<E, V> v, Edge<E, V> u) {
  211.         return false;
  212.     }
  213.  
  214.     public boolean areAdjacent(Node<Vertex<V>> v, Node<Vertex<V>> u) {
  215.         return false;
  216.     }
  217.  
  218.     public int degree(Node<Vertex<V>> v) {
  219.         return 0;
  220.     }
  221. }
  222.  
  223. class DynamicGraph<V extends Number> extends CommonDynamicGraph<V, Double> {
  224.     public DynamicGraph(int n) {
  225.         super(n);
  226.     }
  227.  
  228.     @Override
  229.     public Edge<Double, V> insertEdge(Node<Vertex<V>> from, Node<Vertex<V>> to, Double cost) {
  230.         Edge<Double, V> edge1 = new Edge<>(cost / (from.value.cost.doubleValue() + to.value.cost.doubleValue()), from, to, -1);
  231.         Edge<Double, V> edge2 = new Edge<>(cost / (from.value.cost.doubleValue() + to.value.cost.doubleValue()), to, from, -1);
  232.         if (matrix.size() <= from.value.indexVertex || matrix.size() <= to.value.indexVertex)
  233.             for (int i = matrix.size(); i <= Integer.max(from.value.indexVertex, to.value.indexVertex); i++)
  234.                 matrix.add(new ArrayList<>(n));
  235.  
  236.         if (from.value.indexVertex >= matrix.get(to.value.indexVertex).size())
  237.             for (int i = 0, tempSize = from.value.indexVertex - matrix.get(to.value.indexVertex).size(); i <= tempSize; i++)
  238.                 matrix.get(to.value.indexVertex).add(null);
  239.  
  240.         if (to.value.indexVertex >= matrix.get(from.value.indexVertex).size())
  241.             for (int i = 0, tempSize = to.value.indexVertex - matrix.get(from.value.indexVertex).size(); i <= tempSize; i++)
  242.                 matrix.get(from.value.indexVertex).add(null);
  243.  
  244.         matrix.get(from.value.indexVertex).set(to.value.indexVertex, edge1);
  245.         matrix.get(to.value.indexVertex).set(from.value.indexVertex, edge2);
  246.         return edge1;
  247.     }
  248. }
  249.  
  250.  
  251. interface IPriorityQueue<K extends Comparable<K>, V extends Comparable<V>> {
  252.  
  253.     void Check();
  254.  
  255.     int size();
  256.  
  257.     void insert(K newKey, Node<V> newValue);
  258.  
  259.     Node<V> findMin();
  260.  
  261.     Node<V> extractMin();
  262.  
  263.     void decreaseKey(Node<V> node, K newKey);
  264.  
  265.     void delete(K key, V value);
  266.  
  267.     public K getKeyByValue(Node<V> value);
  268.  
  269.     void union(BinaryHeap<K, V> anotherQueue);
  270.  
  271.     void union(List<Pair<K, Node<V>>> anotherList);
  272. }
  273.  
  274. class Node<V extends Comparable<V>> implements Comparable<Node<V>> {
  275.     V value;
  276.     int indexNode;
  277.  
  278.     public Node(V value, int index) {
  279.         this.value = value;
  280.         this.indexNode = index;
  281.     }
  282.  
  283.     @Override
  284.     public String toString() {
  285.         return value.toString();
  286.     }
  287.  
  288.     @Override
  289.     public int compareTo(Node<V> o) {
  290.         return this.value.compareTo(o.value);
  291.     }
  292. }
  293.  
  294. class BinaryHeap<K extends Comparable<K>, V extends Comparable<V>> implements IPriorityQueue<K, V> {
  295.     int tailIndex;
  296.     protected Pair<K, Node<V>>[] arrayHeap;
  297.  
  298.     private void heapify(int index) {
  299.         if (arrayHeap[(index - 1) / 2].compareTo(arrayHeap[index]) > 0)
  300.             bubbleUp(index);
  301.             // если объект больше детей по ключу
  302.         else
  303.             bubbleDown(index);
  304.     }
  305.  
  306.     @Override
  307.     public void Check() {
  308.         for (int i = 0; i < tailIndex; i++)
  309.             if (arrayHeap[i].getValue().indexNode != i)
  310.                 System.out.println(i + "\n");
  311.     }
  312.  
  313.     private void bubbleDown(int index) {
  314.         if ((2 * index + 2) < tailIndex) {
  315.             if (arrayHeap[index].compareTo(arrayHeap[2 * index + 1]) > 0 && arrayHeap[2 * index + 1].compareTo(arrayHeap[2 * index + 2]) <= 0) {
  316.                 swap(2 * index + 1, index);
  317.                 bubbleDown(2 * index + 1);
  318.             } else if (arrayHeap[index].compareTo(arrayHeap[2 * index + 2]) > 0 && arrayHeap[2 * index + 1].compareTo(arrayHeap[2 * index + 2]) > 0) {
  319.                 swap(2 * index + 2, index);
  320.                 bubbleDown(2 * index + 2);
  321.             }
  322.  
  323.         } else if ((2 * index + 1) < tailIndex) {
  324.             if (arrayHeap[index].compareTo(arrayHeap[2 * index + 1]) > 0) {
  325.                 swap(2 * index + 1, index);
  326.                 bubbleDown(2 * index + 1);
  327.             }
  328.         }
  329.     }
  330.  
  331.     private void swap(int iA, int iB) {
  332.         Pair<K, Node<V>> temp = arrayHeap[iA];
  333.         arrayHeap[iA] = arrayHeap[iB];
  334.         arrayHeap[iB] = temp;
  335.  
  336.         arrayHeap[iA].getValue().indexNode = iA;
  337.         arrayHeap[iB].getValue().indexNode = iB;
  338.     }
  339.  
  340.     private void bubbleUp(int index) {
  341.         // если объект меньше родителя
  342.         int a = (index - 1) / 2, b = index;
  343.         while (arrayHeap[a].compareTo(arrayHeap[b]) > 0) {
  344.             swap(a, b);
  345.  
  346.             b = a;
  347.             a = (b - 1) / 2;
  348.         }
  349.     }
  350.  
  351.  
  352.     public BinaryHeap() {
  353.         tailIndex = 0;
  354.         arrayHeap = new Pair[4000 + 100];
  355.     }
  356.  
  357.     @Override
  358.     public K getKeyByValue(Node<V> value) {
  359.         if (tailIndex <= value.indexNode || value.indexNode == -1)
  360.             return null;
  361.         else
  362.             return arrayHeap[value.indexNode].getKey();
  363.     }
  364.  
  365.     @Override
  366.     public int size() {
  367.         return tailIndex;
  368.     }
  369.  
  370.     @Override
  371.     public void insert(K newKey, Node<V> newValue) {
  372.         arrayHeap[tailIndex] = new Pair<K, Node<V>>(newKey, newValue);
  373.         newValue.indexNode = tailIndex;
  374.         // добавляю элемент в конец, но затем мне нужно его поднять
  375.         heapify(tailIndex);
  376.         tailIndex++;
  377.     }
  378.  
  379.     @Override
  380.     public Node<V> findMin() {
  381.         if (tailIndex != 0)
  382.             return arrayHeap[0].getValue();
  383.         else
  384.             return null;
  385.     }
  386.  
  387.     @Override
  388.     public Node<V> extractMin() {
  389.         if (tailIndex != 0) {
  390.             Node<V> returnValue = arrayHeap[0].getValue();
  391.             arrayHeap[0].getValue().indexNode = -1;
  392.             arrayHeap[0] = arrayHeap[tailIndex - 1];
  393.             arrayHeap[0].getValue().indexNode = 0;
  394.             tailIndex--;
  395.             //проверка Up and Bubble Down
  396.             // если объект меньше родителя по ключу
  397.             heapify(0);
  398.             return returnValue;
  399.         } else return null;
  400.     }
  401.  
  402.     @Override
  403.     public void decreaseKey(Node<V> node, K newKey) {
  404.         if (arrayHeap[node.indexNode].getValue().compareTo(node) == 0 && tailIndex > node.indexNode) {
  405.             arrayHeap[node.indexNode].setKey(newKey);
  406.             heapify(node.indexNode);
  407.         }
  408.     }
  409.  
  410.     @Override
  411.     public void delete(K key, V value) {
  412.  
  413.     }
  414.  
  415.     @Override
  416.     public void union(BinaryHeap<K, V> anotherQueue) {
  417.         union(Arrays.asList(anotherQueue.arrayHeap));
  418.     }
  419.  
  420.     @Override
  421.     public void union(List<Pair<K, Node<V>>> anotherList) {
  422.         for (int i = 0; i < anotherList.size(); i++, tailIndex++) {
  423.             arrayHeap[tailIndex] = anotherList.get(i);
  424.             arrayHeap[tailIndex].getValue().indexNode = tailIndex;
  425.         }
  426.  
  427.         int index = (tailIndex - 2) / 2;
  428.  
  429.         for (int i = index; i >= 0; i--)
  430.             heapify(index);
  431.     }
  432. }
  433.  
  434. class Pair<K extends Comparable<K>, V extends Comparable<V>> implements Comparable<Pair<K, V>> {
  435.     private K key;
  436.  
  437.     public K getKey() {
  438.         return key;
  439.     }
  440.  
  441.     public void setKey(K key) {
  442.         this.key = key;
  443.     }
  444.  
  445.     private V value;
  446.  
  447.     public V getValue() {
  448.         return value;
  449.     }
  450.  
  451.     public void setValue(V value) {
  452.         this.value = value;
  453.     }
  454.  
  455.     public Pair(K key, V value) {
  456.         this.key = key;
  457.         this.value = value;
  458.     }
  459.  
  460.     @Override
  461.     public String toString() {
  462.         return key + "=" + value;
  463.     }
  464.  
  465.     @Override
  466.     public int compareTo(Pair<K, V> o) {
  467.         if (o.key.compareTo(this.key) == 0)
  468.             return this.value.compareTo(o.value);
  469.         else return this.key.compareTo(o.key);
  470.     }
  471. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement