Filip_Markoski

[ADSx] - Paytolls

Jan 15th, 2018
202
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 15.68 KB | None | 0 0
  1. import java.util.*;
  2.  
  3. public class Paytolls {
  4.     public static void main(String args[]) {
  5.         /**
  6.          * Between any two cities, there can be at most one two-way road
  7.          * = The graph is undirected, but Bojan's travel is directed thus directed graph
  8.          * */
  9.         Scanner scanner = new Scanner(System.in);
  10.         int citiesCount = scanner.nextInt();
  11.         Graph<String> graph = new Graph<>(citiesCount);
  12.  
  13.         int startId = scanner.nextInt() - 1;
  14.         int endId = scanner.nextInt() - 1;
  15.         int edgesCount = scanner.nextInt();
  16.  
  17.         for (int i = 0; i < edgesCount; i++) {
  18.             int id1 = scanner.nextInt() - 1;
  19.             int id2 = scanner.nextInt() - 1;
  20.             int weight = scanner.nextInt();
  21.             graph.addEdge(id1, id2, weight);
  22.             graph.addEdge(id2, id1, weight);
  23.         }
  24.  
  25.         /* There are no cities
  26.         thus there is no info for which the GraphNode.equals() will work
  27.         * so GraphNode.equals() is changed to compare indexes */
  28.  
  29.         float[] dijkstra = graph.dijkstra(startId);
  30.         System.out.println(Math.round(dijkstra[endId]));
  31.     }
  32. }
  33.  
  34. /**
  35.  * Bojan wants to visit Berlin. But, Bojan is on a limited budget, so he has to choose the optimal path. He rented a car and bought a map of Europe. On it are N cities.
  36.  * Between any two cities, there can be at most one two-way road. For each of those roads, Bojan knows the number of pay tolls..
  37.  * Can you help Bojan, find the route from Skopje to Berlin which has the least number of pay tolls?
  38.  * <p>
  39.  * Input: The first line contains N (2 <= N <= 1000), the number of cities.
  40.  * Each city has a unique id - which ranges from 1 до N.
  41.  * The second line contains A и B (1 <= A, B <= N), the ids of Skopje (А) and Berlin (B).
  42.  * The third line contains M (N <= M <= 1500), the number of direct roads.
  43.  * The next M lines contain X, Y (1 <= X, Y <= N) и K (1 <= K <= 1000), a path from X to Y with K pay tolls.
  44.  * <p>
  45.  * Output: Print the required minimum number of pay tolls.
  46.  */
  47.  
  48. class Edge {
  49.     private int fromVertex, toVertex;
  50.     private float weight;
  51.  
  52.     public Edge(int from, int to, float weight) {
  53.         this.fromVertex = from;
  54.         this.toVertex = to;
  55.         this.weight = weight;
  56.     }
  57.  
  58.     public int getFrom() {
  59.         return this.fromVertex;
  60.     }
  61.  
  62.     public int getTo() {
  63.         return this.toVertex;
  64.     }
  65.  
  66.     public float getWeight() {
  67.         return this.weight;
  68.     }
  69. }
  70.  
  71. class GraphNodeNeighbor<E> {
  72.     GraphNode<E> node;
  73.     float weight;
  74.  
  75.     public GraphNodeNeighbor(GraphNode<E> node, float weight) {
  76.         this.node = node;
  77.         this.weight = weight;
  78.     }
  79.  
  80.     public GraphNodeNeighbor(GraphNode<E> node) {
  81.         this.node = node;
  82.         this.weight = 0;
  83.     }
  84.  
  85.     @Override
  86.     public boolean equals(Object obj) {
  87.         @SuppressWarnings("unchecked")
  88.         GraphNodeNeighbor<E> pom = (GraphNodeNeighbor<E>) obj;
  89.         return pom.node.equals(this.node);
  90.     }
  91.  
  92. }
  93.  
  94. class GraphNode<E> {
  95.     private int index; //index (reden broj) na temeto vo grafot
  96.     private E info;
  97.     private LinkedList<GraphNodeNeighbor<E>> neighbors;
  98.  
  99.     public GraphNode(int index, E info) {
  100.         this.index = index;
  101.         this.info = info;
  102.         neighbors = new LinkedList<GraphNodeNeighbor<E>>();
  103.     }
  104.  
  105.     public boolean containsNeighbor(GraphNode<E> o) {
  106.         GraphNodeNeighbor<E> pom = new GraphNodeNeighbor<E>(o, 0);
  107.         return neighbors.contains(pom);
  108.     }
  109.  
  110.     public void addNeighbor(GraphNode<E> o, float weight) {
  111.         GraphNodeNeighbor<E> pom = new GraphNodeNeighbor<E>(o, weight);
  112.         neighbors.add(pom);
  113.     }
  114.  
  115.     public void removeNeighbor(GraphNode<E> o) {
  116.         GraphNodeNeighbor<E> pom = new GraphNodeNeighbor<E>(o, 0);
  117.         if (neighbors.contains(pom))
  118.             neighbors.remove(pom);
  119.     }
  120.  
  121.     @Override
  122.     public String toString() {
  123.         StringBuilder sb = new StringBuilder("INFO:" + info + " SOSEDI:");
  124.         for (int i = 0; i < neighbors.size(); i++) {
  125.             sb.append("(").append(neighbors.get(i).node.info).append(",").append(neighbors.get(i).weight).append(") ");
  126.         }
  127.         return sb.toString();
  128.  
  129.     }
  130.  
  131.     public void updateNeighborWeight(GraphNode<E> o, float weight) {
  132.         Iterator<GraphNodeNeighbor<E>> i = neighbors.iterator();
  133.         while (i.hasNext()) {
  134.             GraphNodeNeighbor<E> pom = i.next();
  135.             if (pom.node.equals(o))
  136.                 pom.weight = weight;
  137.         }
  138.  
  139.     }
  140.  
  141.     /*
  142.     *
  143.         @Override
  144.         public boolean equals(Object obj) {
  145.             @SuppressWarnings("unchecked")
  146.             GraphNode<E> pom = (GraphNode<E>) obj;
  147.             return (pom.info.equals(this.info));
  148.         }*/
  149.     @Override
  150.     public boolean equals(Object o) {
  151.         if (this == o) return true;
  152.         if (o == null || getClass() != o.getClass()) return false;
  153.  
  154.         GraphNode<?> graphNode = (GraphNode<?>) o;
  155.  
  156.         return this.index == graphNode.index;
  157.     }
  158.  
  159.     @Override
  160.     public int hashCode() {
  161.         return info.hashCode();
  162.     }
  163.  
  164.     public int getIndex() {
  165.         return index;
  166.     }
  167.  
  168.     public void setIndex(int index) {
  169.         this.index = index;
  170.     }
  171.  
  172.     public E getInfo() {
  173.         return info;
  174.     }
  175.  
  176.     public void setInfo(E info) {
  177.         this.info = info;
  178.     }
  179.  
  180.     public LinkedList<GraphNodeNeighbor<E>> getNeighbors() {
  181.         return neighbors;
  182.     }
  183.  
  184.     public void setNeighbors(LinkedList<GraphNodeNeighbor<E>> neighbors) {
  185.         this.neighbors = neighbors;
  186.     }
  187.  
  188.  
  189. }
  190.  
  191. class Graph<E> {
  192.  
  193.     int num_nodes;
  194.     GraphNode<E> adjList[];
  195.  
  196.     @SuppressWarnings("unchecked")
  197.     public Graph(int num_nodes, E[] list) {
  198.         this.num_nodes = num_nodes;
  199.         adjList = (GraphNode<E>[]) new GraphNode[num_nodes];
  200.         for (int i = 0; i < num_nodes; i++)
  201.             adjList[i] = new GraphNode<E>(i, list[i]);
  202.     }
  203.  
  204.     @SuppressWarnings("unchecked")
  205.     public Graph(int num_nodes) {
  206.         this.num_nodes = num_nodes;
  207.         adjList = (GraphNode<E>[]) new GraphNode[num_nodes];
  208.         for (int i = 0; i < num_nodes; i++)
  209.             adjList[i] = new GraphNode<E>(i, null);
  210.     }
  211.  
  212.     int adjacent(int x, int y) {
  213.         // proveruva dali ima vrska od jazelot so
  214.         // indeks x do jazelot so indeks y
  215.         return (adjList[x].containsNeighbor(adjList[y])) ? 1 : 0;
  216.     }
  217.  
  218.     void addEdge(int x, int y, float tezina) {
  219.         // dodava vrska od jazelot so indeks x do jazelot so indeks y so tezina
  220.         if (adjList[x].containsNeighbor(adjList[y])) {
  221.             adjList[x].updateNeighborWeight(adjList[y], tezina);
  222.         } else
  223.             adjList[x].addNeighbor(adjList[y], tezina);
  224.     }
  225.  
  226.     void deleteEdge(int x, int y) {
  227.         adjList[x].removeNeighbor(adjList[y]);
  228.     }
  229.  
  230.     /*************************** KRUSKAL ***********************************************************************/
  231.     // Metoda koja generira niza od site rebra vo grafot
  232.     public Edge[] getAllEdges() {
  233.         int totalEdges = 0;
  234.         for (int i = 0; i < this.num_nodes; i++) {
  235.             // za sekoe teme go dodavame brojot na sosedi koi gi ima
  236.             totalEdges += this.adjList[i].getNeighbors().size();
  237.         }
  238.  
  239.         // System.out.println("METODA: Imame vk "+totalEdges+" rebra");
  240.  
  241.         Edge[] edges = new Edge[totalEdges];
  242.         int index = 0;
  243.         for (int i = 0; i < this.num_nodes; i++) {
  244.             for (int j = 0; j < this.adjList[i].getNeighbors().size(); j++) {
  245.                 int index1 = this.adjList[i].getIndex();
  246.                 // se zemaat indeksot i tezinata na j-ot sosed na temeto i
  247.                 int index2 = this.adjList[i].getNeighbors().get(j).node
  248.                         .getIndex();
  249.                 float weight = this.adjList[i].getNeighbors().get(j).weight;
  250.                 edges[index++] = new Edge(index1, index2, weight);
  251.             }
  252.         }
  253.  
  254.         return edges;
  255.     }
  256.  
  257.     // Metoda koja gi sortira site rebra
  258.     private Edge[] sortEdges(Edge[] edges) {
  259.         for (int i = 0; i < edges.length - 1; i++) {
  260.             for (int j = i + 1; j < edges.length; j++) {
  261.                 if (edges[i].getWeight() > edges[j].getWeight()) {
  262.                     Edge tmp = edges[i];
  263.                     edges[i] = edges[j];
  264.                     edges[j] = tmp;
  265.                 }
  266.             }
  267.         }
  268.  
  269.         return edges;
  270.     }
  271.  
  272.     // Metoda koja pravi unija na dve drva
  273.     private int[] union(int u, int v, int[] vrski) {
  274.         int findWhat, replaceWith;
  275.  
  276.         if (u < v) {
  277.             findWhat = vrski[v];
  278.             replaceWith = vrski[u];
  279.         } else {
  280.             findWhat = vrski[u];
  281.             replaceWith = vrski[v];
  282.         }
  283.  
  284.         // za dvete poddrva stava ist index
  285.         // t.e. gi spojuva
  286.         for (int i = 0; i < vrski.length; i++) {
  287.             if (vrski[i] == findWhat) {
  288.                 vrski[i] = replaceWith;
  289.             }
  290.         }
  291.         return vrski;
  292.     }
  293.  
  294.     List<Edge> kruskal() {
  295.         /*
  296.          * Pomoshna niza za sledenje na kreiranite drva Ako dve teminja se del
  297.          * od isto poddrvo togash imaat ista vrednost vo nizata
  298.          */
  299.         int vrski[] = new int[this.num_nodes];
  300.  
  301.         // niza koja gi sodrzi site rebra
  302.         Edge[] edges = this.getAllEdges();
  303.         // se sortiraat rebrata spored tezinite vo neopagjacki redosled
  304.         edges = this.sortEdges(edges);
  305.  
  306.         // inicijalizacija na pomosnata niza za evidencija,
  307.         // sekoj jazel si e posebno drvo
  308.         for (int i = 0; i < this.num_nodes; i++)
  309.             vrski[i] = i;
  310.  
  311.         // lista koja kje gi sodrzi MST rebra
  312.         List<Edge> mstEdges = new ArrayList<Edge>();
  313.  
  314.         for (int i = 0; i < edges.length; i++) {
  315.             // za sekoe rebro vo sortiran redosled
  316.             Edge e = edges[i];
  317.  
  318.             if (vrski[e.getFrom()] != vrski[e.getTo()]) {
  319.                 // ako teminjata na ova rebro ne se vo isto poddrvo
  320.                 // ova rebro e MST rebro
  321.                 mstEdges.add(e);
  322.                 // sega dvete teminja treba da se vo isto poddrvo
  323.                 // t.e se pravi merge (unija) t.s. vo nizata vrski
  324.                 // za site elementi od dvete poddrva
  325.                 // go setira istiot (najmal) element od dvete poddrva
  326.                 vrski = this.union(e.getFrom(), e.getTo(), vrski);
  327.             }
  328.  
  329.             // ako sme dodale num_nodes-1 rebra moze da prestaneme
  330.             if (mstEdges.size() == (this.num_nodes - 1))
  331.                 break;
  332.         }
  333.  
  334.         return mstEdges;
  335.     }
  336.  
  337.     /*******************************************************************************************************/
  338.  
  339.     /************************ PRIM **************************************************************************/
  340.  
  341.     // Metoda koja go naogja najmaloto rebro do
  342.     // teme na neposeten sosed
  343.     private Edge getMinimalEdge(boolean[] included) {
  344.         int index1 = Integer.MAX_VALUE, index2 = Integer.MAX_VALUE;
  345.         float minweight = Float.MAX_VALUE;
  346.  
  347.         for (int i = 0; i < this.num_nodes; i++) {
  348.             if (included[i]) {
  349.                 // ako e vkluceno temeto i
  350.                 // izmini gi negovite nevkluceni sosedi
  351.                 Iterator<GraphNodeNeighbor<E>> it = adjList[i].getNeighbors()
  352.                         .iterator();
  353.                 while (it.hasNext()) {
  354.                     GraphNodeNeighbor<E> pom = it.next();
  355.                     // ako sosedot ne e poseten i ima do sega najmala tezina
  356.                     if (!included[pom.node.getIndex()]
  357.                             && pom.weight < minweight) {
  358.                         index1 = i;
  359.                         index2 = pom.node.getIndex();
  360.                         minweight = pom.weight;
  361.                     }
  362.                 }
  363.             }
  364.         }
  365.  
  366.         if (minweight < Float.MAX_VALUE) {
  367.             Edge ret = new Edge(index1, index2, minweight);
  368.             return ret;
  369.         }
  370.         return null;
  371.     }
  372.  
  373.     List<Edge> prim(int start_index) {
  374.         // lista koja kje gi sodrzi MST rebra
  375.         List<Edge> mstEdges = new ArrayList<Edge>();
  376.  
  377.         boolean included[] = new boolean[this.num_nodes];
  378.         for (int i = 0; i < this.num_nodes; i++)
  379.             included[i] = false;
  380.  
  381.         included[start_index] = true;
  382.  
  383.         for (int i = 0; i < this.num_nodes - 1; i++) {
  384.             Edge e = this.getMinimalEdge(included);
  385.             if (e == null) {
  386.                 System.out.println("Ne mozat da se povrzat site jazli");
  387.                 break;
  388.             }
  389.             included[e.getFrom()] = included[e.getTo()] = true;
  390.             mstEdges.add(e);
  391.         }
  392.  
  393.         return mstEdges;
  394.     }
  395.  
  396.     /*******************************************************************************************************/
  397.     /***************** DIJKSTRA ******************************************************************************/
  398.  
  399.     float[] dijkstra(int from) {
  400.  
  401.         /* Minimalna cena do sekoj od teminjata */
  402.         float distance[] = new float[this.num_nodes];
  403.         /* dali za temeto e najdena konecnata (minimalna) cena */
  404.         boolean finalno[] = new boolean[this.num_nodes];
  405.         for (int i = 0; i < this.num_nodes; i++) {
  406.             distance[i] = -1;
  407.             finalno[i] = false;
  408.         }
  409.  
  410.         finalno[from] = true;
  411.         distance[from] = 0;
  412.  
  413.         /*
  414.          * vo sekoj cekor za edno teme se dobiva konecna minimalna cena
  415.          */
  416.         for (int i = 1; i < this.num_nodes; i++) {
  417.             /* za site sledbenici na from presmetaj ja cenata */
  418.             Iterator<GraphNodeNeighbor<E>> it = adjList[from].getNeighbors().iterator();
  419.             while (it.hasNext()) {
  420.                 GraphNodeNeighbor<E> pom = it.next();
  421.                 /* ako grankata kon sosedot nema konecna cena */
  422.                 if (!finalno[pom.node.getIndex()]) {
  423.                     /* ako ne e presmetana cena za temeto */
  424.                     if (distance[pom.node.getIndex()] <= 0) {
  425.                         distance[pom.node.getIndex()] = distance[from]
  426.                                 + pom.weight;
  427.                     }
  428.                     /* inaku, ako e pronajdena poniska */
  429.                     else if (distance[from] + pom.weight < distance[pom.node
  430.                             .getIndex()]) {
  431.                         distance[pom.node.getIndex()] = distance[from]
  432.                                 + pom.weight;
  433.                     }
  434.                 }
  435.             }
  436.  
  437.             /* najdi teme so min. cena koja ne e konecna */
  438.             boolean minit = false; /* min. ne e inicijaliziran */
  439.             int k = -1;
  440.             float minc = -1;
  441.             /* proveri gi site teminja */
  442.             for (int j = 0; j < this.num_nodes; j++) {
  443.                 if (!finalno[j] && distance[j] != -1) { /*ako cenata ne e  konecna*/
  444.                     if (!minit) { /* ako ne e inicijaliziran minimumot */
  445.                         minc = distance[k = j]; /* proglasi go ova e minimum */
  446.                         minit = true; /* oznaci deka min e inicijaliziran */
  447.                     }
  448.                     /* proveri dali e pronajdeno teme so pomala cena */
  449.                     else if (minc > distance[j] && distance[j] > 0)
  450.                         minc = distance[k = j];
  451.                 }
  452.             }
  453.             finalno[from = k] = true;
  454.         }
  455.  
  456.         return distance;
  457.  
  458.     }
  459.  
  460.     /*******************************************************************************************************/
  461.  
  462.     @Override
  463.     public String toString() {
  464.         StringBuilder ret = new StringBuilder();
  465.         for (int i = 0; i < this.num_nodes; i++)
  466.             ret.append(adjList[i]).append("\n");
  467.         return ret.toString();
  468.     }
  469.  
  470. }
Advertisement
Add Comment
Please, Sign In to add comment