Skip to content

Instantly share code, notes, and snippets.

@pedrotoliveira
Last active December 30, 2015 16:33
Show Gist options
  • Save pedrotoliveira/dc3ab89c1c7135c4b622 to your computer and use it in GitHub Desktop.
Save pedrotoliveira/dc3ab89c1c7135c4b622 to your computer and use it in GitHub Desktop.
A Graph Solution to Find Paths.
import java.io.*;
import java.util.*;
public class Solution {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int m = in.nextInt();
Graph graph = new Graph(n, m);
while (in.hasNextInt()) {
int v1 = in.nextInt();
int v2 = in.nextInt();
graph.addVertice(v1);
graph.addVertice(v2);
graph.addEdge(v1, v2);
}
int count = 0;
Vertice source = new Vertice(1);
DepthFirstSearch dfs = new DepthFirstSearch(graph, source);
//graph.printVertices();
//graph.printMatrix();
//for (Vertice v : graph.getVertices()) {
// System.out.print("Path 1 to " + v.getValue() + ": ");
// for (Vertice i : dfs.pathTo(v)) {
// System.out.print("->" + i);
// }
// System.out.println("");
//}
System.out.println(dfs.count());
}
}
class Vertice implements Comparable<Vertice> {
private int value;
public Vertice(int value) {
this.value = value;
}
public int getValue() {
return value;
}
@Override
public int hashCode() {
int prime = 7;
return prime * value + value;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
return this.value == ((Vertice)obj).value;
}
@Override
public String toString() {
return "V=" + value;
}
@Override
public int compareTo(Vertice o) {
return this.getValue() == o.getValue() ? 0 : this.getValue() - o.getValue();
}
}
class Graph {
private Set<Vertice> vertices;
private Map<Vertice, Set<Vertice>> adjMatrix;
public Graph(int n, int m) {
this.vertices = new LinkedHashSet<>(n);
this.adjMatrix = new HashMap<>(n);
}
public Set<Vertice> getVertices() {
return vertices;
}
public void addVertice(int value) {
this.vertices.add(new Vertice(value));
}
public Vertice getVertice(int value) {
for (Vertice v : vertices) {
if (v.getValue() == value) {
return v;
}
}
return null;
}
public void addEdge(int v1, int v2) {
Vertice vertice1 = getVertice(v1);
Vertice vertice2 = getVertice(v2);
Set<Vertice> verticeSet = new HashSet<>(2);
verticeSet.add(vertice1);
if (adjMatrix.containsKey(vertice2)) {
adjMatrix.get(vertice2).addAll(verticeSet);
} else {
adjMatrix.put(vertice2, verticeSet);
}
}
public Set<Vertice> getEdges(Vertice vertice) {
Set<Vertice> adjacents = new HashSet<>();
if (adjMatrix.containsKey(vertice)) {
adjacents.addAll(adjMatrix.get(vertice));
}
return adjacents;
}
public void printVertices() {
System.out.println("Vertices: " + vertices);
}
public void printMatrix() {
System.out.print("Matrix: ");
for(Vertice v : adjMatrix.keySet()) {
System.out.print("[" + v + "->" + String.valueOf(adjMatrix.get(v)) + "] ");
}
System.out.println("");
}
}
class DepthFirstSearch {
private final Graph graph;
private final Vertice sourceVertice;
private List<Vertice> visited;
private int count = 0;
public DepthFirstSearch(final Graph graph, Vertice sourceVertice) {
this.graph = graph;
this.sourceVertice = sourceVertice;
this.visited = new ArrayList<>();
dfs(graph, sourceVertice);
//System.out.println("Visited: " + visited);
}
private int dfs(final Graph graph, Vertice vertice) {
int verts = 0;
visited.add(vertice);
Set<Vertice> edges = graph.getEdges(vertice);
for(Vertice edge : edges) {
if (!hasPathTo(edge)) {
int nodes = dfs(graph, edge);
if (nodes % 2 == 0) {
count++;
} else {
verts +=nodes;
}
}
}
return verts + 1;
}
public boolean hasPathTo(Vertice vertice) {
return visited.contains(vertice);
}
public int count() {
return count;
}
public List<Vertice> pathTo(Vertice vertice) {
final List<Vertice> path = new ArrayList<>();
if (sourceVertice.equals(vertice)) {
path.add(sourceVertice);
return path;
}
if (hasPathTo(vertice)) {
path.add(sourceVertice);
for (Vertice adj : graph.getEdges(sourceVertice)) {
if (adj.equals(vertice)) {
path.add(adj);
} else {
adjacentPath(vertice, adj, path);
}
}
}
Collections.sort(path);
return path;
}
private void adjacentPath(final Vertice vertice, final Vertice adj, final List<Vertice> path) {
Set<Vertice> edges = graph.getEdges(adj);
for (Vertice edge : edges) {
if (edge.equals(vertice)) {
path.add(adj);
path.add(edge);
} else {
adjacentPath(vertice, edge, path);
if (path.contains(vertice) && path.contains(edge)) {
path.add(adj);
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment