//有向图判定
import java.util.Stack;
public class DirectedCircle {
private boolean[] marked;
private boolean[] onStack;
private int[] edgeTo;
private Stack<Integer> circle;
public DirectedCircle(Graph G) {
marked = new boolean[G.V()];
onStack = new boolean[G.V()];
edgeTo = new int[G.V()];
for (int i = 0; i< G.V(); i++) {
if (!marked[i]) {
dfs(G, i);
}
}
}
private void dfs(Graph G, int v) {
onStack[v] = true;
marked[v] = true;
for (int w : G.adj(v)) {
if (this.hasCircle()) return;
else if (!marked[w]) {
edgeTo[w] = v;
dfs(G, w);
} else if (onStack[w]) {
circle = new Stack<>();
for (int i = v; i != w; i = edgeTo[v]) {
circle.push(i);
}
circle.push(w);
circle.push(v);
}
}
onStack[v] = false;
}
public Iterable<Integer> circle() {
return circle;
}
private boolean hasCircle() {
return circle != null;
}
}
//拓扑排序
import java.util.Stack;
public class DFSorder {
private Stack<Integer> reversePost;
private boolean[] marked;
public DFSorder(Graph G) {
reversePost = new Stack<>();
marked = new boolean[G.V()];
for (int v = 0; v < G.V(); v++) {
dfs(G, v);
}
}
private void dfs(Graph G, int v) {
marked[v] = true;
for (int w; G.adj(v)) {
if (!marked[w]) {
dfs(G, w);
}
}
reversePost.push(v);
}
public Iterable<Integer> reversePost() {
return reversePost;
}
}
//Kosaraju算法实现强连通分量
public class KosarajuSharirSCC {
private int[] id;
private int count;
private boolean[] marked;
public KosarajuSharirSCC(Graph G) {
marked = new boolean[G.V()];
id = new int[G.V()];
DFSorder order = new DFSorder(G);
for (int s : order.reversePost()) {
if (!isMarked(s)) {
dfs(G,s);
count++;
}
}
}
private void dfs(Graph G, int s) {
marked[s] =true;
id[s] = count;
for (int w : G.adj(s)) {
if (!isMarked(w)) {
dfs(w);
}
}
}
private boolean isMarked(int v) {
return marked[v];
}
public int id(int v) {
return id[v];
}
public boolean isConnected(int w, int v) {
return id[v] == id[w];
}
}