import java.util.*;
import sk.upjs.paz.*;
public class Grafy {
/**
* Realizuje prehladavanie do sirky
*
* @param g
* graf, v ktorom sa realizuje prehladavanie
* @param start
* startovaci vrchol, v ktorom startujeme vyhladavanie
*
* @return mapa, ktora urcuje, ci sa vrchol navstivil podla prehladavania
*/
public static Map<Vertex, Integer> bfs(Graph g, Vertex start) {
// Vytvorime mapu
Map<Vertex, Integer> navstiveny = new HashMap<Vertex, Integer>();
// Oznacime vsetky vrcholy ako nenavstivene
for (Vertex v : g.getVertices())
navstiveny.put(v, -1);
// Vytvorime rad pre navstivene vrcholy, ktorych susedov sme zatial
// neskusali navstivit
Queue<Vertex> rad = new LinkedList<Vertex>();
// Na zaciatku je navstiveny iba startovaci vrchol
navstiveny.put(start, 0);
rad.offer(start);
// Kym rad nie je prazdny
while (!rad.isEmpty()) {
// Vyberieme prvy vrchol v rade
Vertex v = rad.poll();
// Postupne vsetkych nenavstivenych susedov vrcholu v oznacime ako
// navstivenych a pridame ich do radu
for (Vertex sused : v.getOutNeighbours())
if (navstiveny.get(sused) == -1) {
navstiveny.put(sused, navstiveny.get(v) + 1);
rad.offer(sused);
}
}
return navstiveny;
}
/**
* Realizuje rekurzivne prehladavanie do hlbky
*
* @param v
* vrchol, ktory ideme navstivit
* @param navstiveny
* mapa, v ktorej mame informaciu o tom, ktore vrcholi boli
* navstivene
*/
public static void dfs(Vertex v, Map<Vertex, Boolean> navstiveny) {
navstiveny.put(v, true);
// Navstivime vsetkych nenavstivenych susedov
for (Vertex sused : v.getOutNeighbours())
if (!navstiveny.get(sused))
dfs(sused, navstiveny);
}
/**
* Realizuje (spusti) rekurzivne prehladavanie do hlbky
*
* @param g
* graf, v ktorom sa realizuje prehladavanie
* @param start
* startovaci vrchol, v ktorom startujeme vyhladavanie
*
* @return mapa, ktora urcuje, ci sa vrchol navstivil podla prehladavania
*/
public static Map<Vertex, Boolean> dfsRekurzivne(Graph g, Vertex start) {
// Vytvorime mapu
Map<Vertex, Boolean> navstiveny = new HashMap<Vertex, Boolean>();
// Oznacime vsetky vrcholy ako nenavstivene
for (Vertex v : g.getVertices())
navstiveny.put(v, false);
// Spustime vyhladavanie z aktualneho vrchola
dfs(start, navstiveny);
return navstiveny;
}
/**
* Realizuje nerekurzivne prehladavanie do hlbky
*
* @param g
* graf, v ktorom sa realizuje prehladavanie
* @param start
* startovaci vrchol, v ktorom startujeme vyhladavanie
*
* @return mapa, ktora urcuje, ci sa vrchol navstivil podla prehladavania
*/
public static Map<Vertex, Boolean> dfsNerekurzivne(Graph g, Vertex start) {
// Vytvorime mapu
Map<Vertex, Boolean> navstiveny = new HashMap<Vertex, Boolean>();
// Oznacime vsetky vrcholy ako nenavstivene
for (Vertex v : g.getVertices())
navstiveny.put(v, false);
// Vytvorime zasobnik na vrcholy, ktore treba navstivit
Stack<Vertex> zasobnik = new Stack<Vertex>();
// Na zaciatku je navstiveny iba startovaci vrchol
navstiveny.put(start, true);
zasobnik.push(start);
while (!zasobnik.isEmpty()) {
// Vyberieme vrchol z vrchu zasobnika
Vertex v = zasobnik.pop();
// Postupne vsetkych nenavstivenych susedov vrcholu v oznacime ako
// navstivenych a pridame ich na vrch zasobnika
for (Vertex sused : v.getOutNeighbours())
if (!navstiveny.get(sused)) {
navstiveny.put(sused, true);
zasobnik.push(sused);
}
}
return navstiveny;
}
public static List<Vertex> cestaZ(Map<Vertex, Integer> vzdialenosti,
Vertex kam) {
if (vzdialenosti.get(kam) == -1)
return null;
List<Vertex> vysledok = new ArrayList<Vertex>();
Vertex aktualny = kam;
while (vzdialenosti.get(aktualny) > 0) {
vysledok.add(aktualny);
Vertex najblizsi = aktualny;
for (Vertex sused : aktualny.getInNeighbours())
if (vzdialenosti.get(sused) < vzdialenosti.get(najblizsi)) {
najblizsi = sused;
}
aktualny = najblizsi;
}
vysledok.add(aktualny);
Collections.reverse(vysledok);
return vysledok;
}
// Vytvori ku neohodnotenemu grafu prisluchajucu maticu susednosti
public static boolean[][] grafNaMaticuSusednosti(Graph g) {
// Vyrobime pole vrcholov
Vertex[] vrcholy = new Vertex[g.getVertices().size()];
int idx = 0;
for (Vertex v : g.getVertices()) {
vrcholy[idx] = v;
idx++;
}
// Vyrobime maticu susednosti
boolean[][] matica = new boolean[vrcholy.length][vrcholy.length];
for (int i = 0; i < vrcholy.length; i++)
for (int j = 0; j < vrcholy.length; j++)
matica[i][j] = g.hasEdge(vrcholy[i], vrcholy[j]);
return matica;
}
public static void bfsSMaticou(boolean[][] matica, int start,
boolean[] bolNavstiveny) {
Queue<Integer> rad = new LinkedList<Integer>();
rad.offer(start);
bolNavstiveny[start] = true;
while(!rad.isEmpty()){
int v = rad.poll();
for (int i = 0; i < bolNavstiveny.length; i++) {
if ((matica[i][v] == true)&& (bolNavstiveny[i]==false)) {
bolNavstiveny[i]=true;
rad.offer(i);
}
}
}
}
public static boolean jeNejakyNenavstiveny(boolean[] bolNavstiveny) {
for (int i = 0; i < bolNavstiveny.length; i++) {
if (bolNavstiveny[i] == false) {
return true;
}
}
return false;
}
public static int nejakyNenavstivenyIdx(boolean[] bolNavstiveny) {
for (int i = 0; i < bolNavstiveny.length; i++) {
if (bolNavstiveny[i] == false) {
return i;
}
}
return -1;
}
public static int pocetKomponentov(boolean[][] matica) {
boolean[] bolNavstiveny = new boolean[matica.length];
int vysledok = 0;
while (jeNejakyNenavstiveny(bolNavstiveny)) {
bfsSMaticou(matica, nejakyNenavstivenyIdx(bolNavstiveny),
bolNavstiveny);
vysledok++;
}
return vysledok;
}
/**
* @param args
*/
public static void main(String[] args) {
// Vytvorime graf
Graph fb = new Graph();
// Nacitame zoznam hran zo suboru
fb.loadFromFile("graf.txt");
boolean[][] matica = grafNaMaticuSusednosti(fb);
System.out.println(pocetKomponentov(matica));
System.out.println(bfs(fb, fb.getVertex("1")));
}
}