Advertisement
teodor_dalavera

Патарини

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