最大流DINIC算法JAVA板子

版权声明: 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;
	}
}

猜你喜欢

转载自blog.csdn.net/King8611/article/details/83177252
今日推荐