Topological Sort
重置不含有循环的图, 使所有连接都指向上面。
算法:
后序遍历graph, 并插入到stack; stack将其方向调换。
// postOrder : operate when the pointer leaves the node
// a diagraph may have topological order if there is no directed cycle!!!
class TopologicalSort {
boolean[] marked;
Stack<Integer> reversePost;
public TopologicalSort(Graph G) {
marked = new boolean[G.V()];
reversePost = new Stack<>();
for (int v = 0; v < G.V(); v++) {
if (!marked) {
dfs(G, v);
}
}
}
private void dfs(Graph G, int v) {
marked[v] = true;
for (int w : G.adj(v)) {
if (!marked) {
dfs(G, w);
}
}
reversePost.push(v);
}
private Iterable<Integer> reversePost() {
return reversePost;
}
}
Kosaraju-Sharir algorithm(计算Strong component)
用一个array来记录component序号(0,1,2…);
先将graph箭头倒置,然后postOrder遍历,然后正序遍历,用array记录component序号。(Strong-component,就是有循环部分)
即反方向遍历一遍,在根据遍历的顺序,正方向遍历一遍。
- Undirected Graph
class CC {
boolean[] marked;
int count;
int[] id;
public CC(Graph G) {
marked = new boolean[G.V()];
id = new int[G.V()];
DFS dfs = new DFS(G.reverse());
for (int v: G.reversePost()) {
if (!marked) {
dfs(G, v);
count++;
}
}
}
public void dfs(Graph G, int v) {
marked[v] = true;
int[v] = count;
for (int w : G.adj(v)) {
if (!marked) {
dfs(G, w);
}
}
}
public boolean isConnected(int v, int w) {
return id[v] == id[w];
}
}
- Directed Grapg
class CC {
boolean[] marked;
int count;
int[] id;
public CC(Graph G) {
marked = new boolean[G.V()];
id = new int[G.V()];
for (int v = 0; v < G.V(); v++) {
if (!marked) {
dfs(G, v);
count++;
}
}
}
public void dfs(Graph G, int v) {
marked[v] = true;
int[v] = count;
for (int w : G.adj(v)) {
if (!marked) {
dfs(G, w);
}
}
}
public boolean isConnected(int v, int w) {
return id[v] == id[w];
}
}