Skip to content

Commit 5e823ef

Browse files
committed
feat: FindBridges
1 parent c44daef commit 5e823ef

File tree

9 files changed

+303
-0
lines changed

9 files changed

+303
-0
lines changed
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package graph_bridges;
2+
3+
public class Edge implements Comparable<Edge> {
4+
private int a;
5+
private int b;
6+
private double weight;
7+
8+
public Edge() {
9+
10+
}
11+
12+
public Edge(int a, int b, double weight) {
13+
this.a = a;
14+
this.b = b;
15+
this.weight = weight;
16+
}
17+
18+
public int v() {
19+
return a;
20+
}
21+
22+
public int w() {
23+
return b;
24+
}
25+
26+
public double wt() {
27+
return weight;
28+
}
29+
30+
public int other(int x) {
31+
assert (x == a || x == b);
32+
return x == a ? b : a;
33+
}
34+
35+
@Override
36+
public int compareTo(Edge o) {
37+
return Double.compare(this.wt(), o.wt());
38+
}
39+
40+
@Override
41+
public String toString() {
42+
return String.format("%d-%d %.2f", a, b, wt());
43+
}
44+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package graph_bridges;
2+
3+
import java.util.ArrayList;
4+
5+
public class FindBridges {
6+
7+
private Graph G;
8+
private boolean[] visited;
9+
10+
private int ord[];
11+
private int low[];
12+
private int cnt;
13+
14+
private ArrayList<Edge> res;
15+
16+
public FindBridges(Graph G) {
17+
18+
this.G = G;
19+
visited = new boolean[G.V()];
20+
ord = new int[G.V()];
21+
low = new int[G.V()];
22+
cnt = 0;
23+
res = new ArrayList<>();
24+
25+
for (int v = 0; v < G.V(); v++)
26+
if (!visited[v])
27+
dfs(v, v);
28+
}
29+
30+
private void dfs(int v, int parent) {
31+
visited[v] = true;
32+
ord[v] = cnt;
33+
low[v] = ord[v];
34+
cnt++;
35+
36+
for (int w : G.adj(v)) {
37+
if (!visited[w]) {
38+
dfs(w, v);
39+
low[v] = Math.min(low[v], low[w]);
40+
if (low[w] > ord[v]) {
41+
// v-w 是桥
42+
res.add(new Edge(v, w, 1));
43+
}
44+
} else if (w != parent) {
45+
low[v] = Math.min(low[v], low[w]);
46+
}
47+
}
48+
}
49+
50+
public ArrayList<Edge> result() {
51+
return res;
52+
}
53+
54+
public static void main(String[] args) {
55+
56+
Graph g = new Graph("./GraphTheory/src/graph_bridges/g.txt");
57+
FindBridges fb = new FindBridges(g);
58+
System.out.println(fb.result());
59+
60+
Graph g2 = new Graph("./GraphTheory/src/graph_bridges/g2.txt");
61+
FindBridges fb2 = new FindBridges(g2);
62+
System.out.println(fb2.result());
63+
64+
Graph tree = new Graph("./GraphTheory/src/graph_bridges/tree.txt");
65+
FindBridges fb3 = new FindBridges(tree);
66+
System.out.println(fb3.result());
67+
}
68+
}
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
package graph_bridges;
2+
3+
import java.io.File;
4+
import java.io.IOException;
5+
import java.util.TreeSet;
6+
import java.util.Scanner;
7+
8+
9+
/// 暂时只支持无向无权图
10+
public class Graph {
11+
12+
private int V;
13+
private int E;
14+
private TreeSet<Integer>[] adj;
15+
16+
public Graph(String filename) {
17+
18+
File file = new File(filename);
19+
20+
try (Scanner scanner = new Scanner(file)) {
21+
22+
V = scanner.nextInt();
23+
if (V < 0) throw new IllegalArgumentException("V must be non-negative");
24+
adj = new TreeSet[V];
25+
for (int i = 0; i < V; i++)
26+
adj[i] = new TreeSet<Integer>();
27+
28+
E = scanner.nextInt();
29+
if (E < 0) throw new IllegalArgumentException("E must be non-negative");
30+
31+
for (int i = 0; i < E; i++) {
32+
int a = scanner.nextInt();
33+
validateVertex(a);
34+
int b = scanner.nextInt();
35+
validateVertex(b);
36+
37+
if (a == b) throw new IllegalArgumentException("Self Loop is Detected!");
38+
if (adj[a].contains(b)) throw new IllegalArgumentException("Parallel Edges are Detected!");
39+
40+
adj[a].add(b);
41+
adj[b].add(a);
42+
}
43+
} catch (IOException e) {
44+
e.printStackTrace();
45+
}
46+
}
47+
48+
public void validateVertex(int v) {
49+
if (v < 0 || v >= V)
50+
throw new IllegalArgumentException("vertex " + v + "is invalid");
51+
}
52+
53+
public int V() {
54+
return V;
55+
}
56+
57+
public int E() {
58+
return E;
59+
}
60+
61+
public boolean hasEdge(int v, int w) {
62+
validateVertex(v);
63+
validateVertex(w);
64+
return adj[v].contains(w);
65+
}
66+
67+
public Iterable<Integer> adj(int v) {
68+
validateVertex(v);
69+
return adj[v];
70+
}
71+
72+
public int degree(int v) {
73+
validateVertex(v);
74+
return adj[v].size();
75+
}
76+
77+
@Override
78+
public String toString() {
79+
StringBuilder sb = new StringBuilder();
80+
81+
sb.append(String.format("V = %d, E = %d\n", V, E));
82+
for (int v = 0; v < V; v++) {
83+
sb.append(String.format("%d : ", v));
84+
for (int w : adj[v])
85+
sb.append(String.format("%d ", w));
86+
sb.append('\n');
87+
}
88+
return sb.toString();
89+
}
90+
91+
public static void main(String[] args) {
92+
93+
Graph g = new Graph("graph_bridges/g.txt");
94+
System.out.print(g);
95+
}
96+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package graph_bridges;
2+
3+
import java.util.ArrayList;
4+
5+
public class GraphDFS {
6+
7+
private Graph G;
8+
private boolean[] visited;
9+
10+
private ArrayList<Integer> pre = new ArrayList<>();
11+
private ArrayList<Integer> post = new ArrayList<>();
12+
13+
public GraphDFS(Graph G) {
14+
15+
this.G = G;
16+
visited = new boolean[G.V()];
17+
for (int v = 0; v < G.V(); v++)
18+
if (!visited[v])
19+
dfs(v);
20+
}
21+
22+
private void dfs(int v) {
23+
24+
visited[v] = true;
25+
pre.add(v);
26+
for (int w : G.adj(v))
27+
if (!visited[w])
28+
dfs(w);
29+
post.add(v);
30+
}
31+
32+
public Iterable<Integer> pre() {
33+
return pre;
34+
}
35+
36+
public Iterable<Integer> post() {
37+
return post;
38+
}
39+
40+
public static void main(String[] args) {
41+
42+
Graph g = new Graph("graph_bridges/g.txt");
43+
GraphDFS graphDFS = new GraphDFS(g);
44+
System.out.println("DFS preOrder : " + graphDFS.pre());
45+
System.out.println("DFS postOrder : " + graphDFS.post());
46+
}
47+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
7 8
2+
0 1
3+
0 2
4+
1 3
5+
2 3
6+
3 5
7+
4 5
8+
4 6
9+
5 6
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
12 16
2+
0 1
3+
0 2
4+
1 3
5+
2 3
6+
3 5
7+
4 5
8+
4 6
9+
4 7
10+
5 6
11+
6 8
12+
8 9
13+
8 10
14+
8 11
15+
9 10
16+
9 11
17+
10 11
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
4 5
2+
0 1
3+
0 2
4+
1 2
5+
1 3
6+
2 3
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
7 8
2+
0 1
3+
0 2
4+
1 3
5+
1 4
6+
2 3
7+
2 6
8+
3 5
9+
5 6
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
7 6
2+
0 1
3+
0 3
4+
1 6
5+
2 3
6+
2 5
7+
3 4

0 commit comments

Comments
 (0)