1. 程式人生 > >最大流DINIC演算法JAVA板子

最大流DINIC演算法JAVA板子

推薦一條部落格:

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;
	}
}