Last active
March 29, 2016 08:23
-
-
Save cyclotimia/36afd03b409f7465adff to your computer and use it in GitHub Desktop.
finding cut points in a graph
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
задача: https://stepic.org/lesson/%D0%A1%D1%82%D1%80%D1%83%D0%BA%D1%82%D1%83%D1%80%D0%B0-%D0%B4%D0%B2%D1%83%D1%81%D0%B2%D1%8F%D0%B7%D0%BD%D1%8B%D1%85-%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2-12342/step/11?unit=6526 | |
Найдите все точки сочленения в графе. | |
На вход программе подаётся описание графа, состоящее не более чем из 100000 строк. | |
Каждая строка описывает очередное ребро: содержит два номера вершин, которые данное ребро соединяет. | |
Номера разделены пробелом. Гарантируется, что ребра определяют связный граф, вершины которого | |
пронумерованы числами от 0 до некоторого n. | |
Выведите единственную строку — список номеров точек сочленения графа через пробел. | |
Sample Input: | |
0 1 | |
1 2 | |
2 0 | |
3 2 | |
4 3 | |
4 2 | |
5 4 | |
Sample Output: | |
2 4 | |
*/ | |
import java.io.BufferedReader; | |
import java.io.InputStream; | |
import java.util.*; | |
class Pair<T, M> { | |
private final T first; | |
private final M second; | |
// конструктор | |
private Pair(T value1, M value2) { | |
this.first = value1; | |
this.second = value2; | |
} | |
// получить первый эл-т пары | |
public T getFirst() { | |
return this.first; | |
} | |
// получить второй эл-т пары | |
public M getSecond() { | |
return this.second; | |
} | |
// equals | |
@Override | |
public boolean equals(Object obj) { | |
if (this == obj) return true; | |
if (obj == null || getClass() != obj.getClass()) return false; | |
Pair<?, ?> pair = (Pair<?, ?>) obj; | |
if (first != null ? !first.equals(pair.first) : pair.first != null) return false; | |
return !(second != null ? !second.equals(pair.second) : pair.second != null); | |
} | |
// hashcode | |
@Override | |
public int hashCode() { | |
int result = first != null ? first.hashCode() : 0; | |
result = 31 * result + (second != null ? second.hashCode() : 0); | |
return result; | |
} | |
// конструктор | |
public static <T, M> Pair of(T value1, M value2) { | |
return new Pair(value1, value2); | |
} | |
} | |
class Graph { | |
private int V; // No. of vertices | |
private LinkedList<Integer> adj[]; // Array of lists for Adjacency List Representation | |
int time = 0; | |
static final int NIL = -1; | |
// Constructor | |
Graph(int v) { | |
V = v; | |
adj = new LinkedList[v]; | |
for (int i = 0; i < v; ++i) | |
adj[i] = new LinkedList(); | |
} | |
//Function to add an edge into the graph | |
void addEdge(int v, int w) { | |
adj[v].add(w); // Add w to v's list. | |
adj[w].add(v); //Add v to w's list | |
} | |
// A recursive function that find articulation points using DFS | |
// u --> The vertex to be visited next | |
// visited[] --> keeps tract of visited vertices | |
// disc[] --> Stores discovery times of visited vertices | |
// parent[] --> Stores parent vertices in DFS tree | |
// ap[] --> Store articulation points | |
void APUtil(int u, boolean visited[], int disc[], | |
int low[], int parent[], boolean ap[]) { | |
// Count of children in DFS Tree | |
int children = 0; | |
// Mark the current node as visited | |
visited[u] = true; | |
// Initialize discovery time and low value | |
disc[u] = low[u] = ++time; | |
// Go through all vertices adjacent to this | |
Iterator<Integer> i = adj[u].iterator(); | |
while (i.hasNext()) { | |
int v = i.next(); // v is current adjacent of u | |
// If v is not visited yet, then make it a child of u | |
// in DFS tree and recur for it | |
if (!visited[v]) { | |
children++; | |
parent[v] = u; | |
APUtil(v, visited, disc, low, parent, ap); | |
// Check if the subtree rooted with v has a connection to | |
// one of the ancestors of u | |
low[u] = Math.min(low[u], low[v]); | |
// u is an articulation point in following cases | |
// (1) u is root of DFS tree and has two or more chilren. | |
if (parent[u] == NIL && children > 1) | |
ap[u] = true; | |
// (2) If u is not root and low value of one of its child | |
// is more than discovery value of u. | |
if (parent[u] != NIL && low[v] >= disc[u]) | |
ap[u] = true; | |
} | |
// Update low value of u for parent function calls. | |
else if (v != parent[u]) | |
low[u] = Math.min(low[u], disc[v]); | |
} | |
} | |
void findCutPoints() { | |
// Mark all the vertices as not visited | |
boolean visited[] = new boolean[V]; | |
int disc[] = new int[V]; | |
int low[] = new int[V]; | |
int parent[] = new int[V]; | |
boolean ap[] = new boolean[V]; // To store articulation points | |
// Initialize parent and visited, and ap(articulation point) | |
// arrays | |
for (int i = 0; i < V; i++) { | |
parent[i] = NIL; | |
visited[i] = false; | |
ap[i] = false; | |
} | |
// Call the recursive helper function to find articulation | |
// points in DFS tree rooted with vertex 'i' | |
for (int i = 0; i < V; i++) | |
if (visited[i] == false) | |
APUtil(i, visited, disc, low, parent, ap); | |
// Now ap[] contains articulation points, print them | |
for (int i = 0; i < V; i++) | |
if (ap[i] == true) | |
System.out.print(i + " "); | |
} | |
} | |
public class Main { | |
public static void main(String[] args) { | |
// a set of vertices | |
Set<Integer> vertices = new HashSet<>(); | |
// a list of edges | |
List<Pair<Integer, Integer>> edges = new ArrayList<>(); | |
Scanner scanner = new Scanner(System.in); | |
while (scanner.hasNext()) { | |
int start = scanner.nextInt(); | |
int end = scanner.nextInt(); | |
// adding those to the set of vertices | |
vertices.add(start); | |
vertices.add(end); | |
// making a pair, adding it to the list of edges | |
Pair<Integer, Integer> edge = Pair.of(start, end); | |
edges.add(edge); | |
} | |
Graph graph = new Graph(vertices.size()); | |
for (int i = 0; i < edges.size(); i++) { | |
int a = edges.get(i).getFirst(); | |
int b = edges.get(i).getSecond(); | |
graph.addEdge(a, b); | |
} | |
graph.findCutPoints(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment