-
Notifications
You must be signed in to change notification settings - Fork 68
/
Copy pathMaxFlow.java
108 lines (83 loc) · 2.89 KB
/
MaxFlow.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
import java.util.*;
public class MaxFlow {
private WeightedGraph network;
private int s, t;
private WeightedGraph rG;
private int maxFlow = 0;
public MaxFlow(WeightedGraph network, int s, int t){
if(!network.isDirected())
throw new IllegalArgumentException("MaxFlow only works in directed graph.");
if(network.V() < 2)
throw new IllegalArgumentException("The network should hs at least 2 vertices.");
network.validateVertex(s);
network.validateVertex(t);
if(s == t)
throw new IllegalArgumentException("s and t should be differrent.");
this.network = network;
this.s = s;
this.t = t;
this.rG = new WeightedGraph(network.V(), true);
for(int v = 0; v < network.V(); v ++)
for(int w: network.adj(v)){
int c = network.getWeight(v, w);
rG.addEdge(v, w, c);
rG.addEdge(w, v, 0);
}
while(true){
ArrayList<Integer> augPath = getAugmentingPath();
if(augPath.size() == 0) break;
int f = Integer.MAX_VALUE;
for(int i = 1; i < augPath.size(); i ++) {
int v = augPath.get(i - 1);
int w = augPath.get(i);
f = Math.min(f, rG.getWeight(v, w));
}
maxFlow += f;
for(int i = 1; i < augPath.size(); i ++){
int v = augPath.get(i - 1);
int w = augPath.get(i);
rG.setWeight(v, w, rG.getWeight(v, w) - f);
rG.setWeight(w, v, rG.getWeight(w, v) + f);
}
}
}
private ArrayList<Integer> getAugmentingPath(){
Queue<Integer> q = new LinkedList<>();
int[] pre = new int[network.V()];
Arrays.fill(pre, -1);
q.add(s);
pre[s] = s;
while(!q.isEmpty()){
int cur = q.remove();
if(cur == t) break;
for(int next: rG.adj(cur))
if(pre[next] == -1 && rG.getWeight(cur, next) > 0){
pre[next] = cur;
q.add(next);
}
}
ArrayList<Integer> res = new ArrayList<>();
if(pre[t] == -1) return res;
int cur = t;
while(cur != s){
res.add(cur);
cur = pre[cur];
}
res.add(s);
Collections.reverse(res);
return res;
}
public int result(){
return maxFlow;
}
public int flow(int v, int w){
if(!network.hasEdge(v, w))
throw new IllegalArgumentException(String.format("No edge %d-%d", v, w));
return rG.getWeight(w, v);
}
public static void main(String[] args){
WeightedGraph network = new WeightedGraph("baseball.txt", true);
MaxFlow maxflow = new MaxFlow(network, 0, 10);
System.out.println(maxflow.result());
}
}