Advertisement
dzocesrce

[APS] River Pollution

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