版权声明: https://blog.csdn.net/King8611/article/details/83177252
推荐一条博客:
https://www.cnblogs.com/SYCstudio/p/7260613.html
讲解得比较细致。
然后自己理解了一下写了个JAVA得板子,和哪个差不多,去把HDU一道板子题A了:
http://acm.hdu.edu.cn/showproblem.php?pid=3549
之前写过一个EK算法,不过据说不常用:
https://blog.csdn.net/King8611/article/details/81171248
代码:
import java.util.*;
import java.io.*;
public class Main {
static StreamTokenizer in=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
static int grade[];
static int s,t; //超级源,超级汇
static int n; //定点个数
/*前向星存边*/
static int head[];
static Edge[] e;
static int len;
//====================
static void addEdge(int a,int b,int c) { //添加节点
e[len]=new Edge(b,head[a],c); //前向星储存边
head[a]=len;
len++;
}
static void add(int a,int b,int c) { //添加正节点和反节点
addEdge(a,b,c);
addEdge(b,a,0);
}
static boolean bfs() { //bfs分层
LinkedList<Integer> list=new LinkedList<Integer>(); //一个队列,用于分层
grade=new int[n+1];
list.offer(s);
grade[s]=1;
while(!list.isEmpty()) {
int cur=list.poll();
if(cur==t)return true;
for(int i=head[cur];i!=-1;i=e[i].next) {
int v=e[i].v;
if(grade[v]==0&&e[i].w!=0) {
grade[v]=grade[cur]+1;
list.offer(v);
}
}
}
return false;
}
static int dfs(int u,int dist) { //dfs求那啥流量
if(u==t) //找到汇点
return dist;
for(int i=head[u];i!=-1;i=e[i].next) {
if(grade[e[i].v]-1==grade[u]&&e[i].w!=0) {
int di=dfs(e[i].v,Math.min(dist,e[i].w));
if (di>0){ //如果存在一个流,做相应操作
e[i].w-=di;
e[i^1].w+=di;
return di;
}
}
}
return 0;
}
static int Max_Flow() { //求最大流,不断bfs,dfs直到分层不见t
int ans=0;
while(bfs()) {
int d;
do {
d=dfs(s,Integer.MAX_VALUE);
ans+=d;
}
while(d!=0);
}
return ans;
}
static void init() { //重置函数
len=0;
e=new Edge[3000];
grade=new int[n+1];
head=new int[n+1];
for(int i=0;i<=n;i++)
head[i]=-1;
s=1;
t=n;
}
public static void main(String[] args) throws Exception{
int t=getInt();
for(int i=1;i<=t;i++){
n=getInt();
int m=getInt();
init();
while(m--!=0) {
add(getInt(),getInt(),getInt());
}
System.out.println("Case "+i+": "+Max_Flow());
}
}
static int getInt() throws Exception {
in.nextToken();
return (int)in.nval;
}
}
class Edge{
int next; //对应的下一条边
int v; //点
int w; //容量
public Edge() {}
public Edge(int a,int b,int c) { //点,下一条边,容量
this.v=a;
this.next=b;
this.w=c;
}
}