Advertisement
dzocesrce

[APS] Round Trip

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