1. 程式人生 > >求圖的最大流-EdmondsKarp方法

求圖的最大流-EdmondsKarp方法

package com.data.struct;



public class EdmondsKarp {
	private Node[][]graphic;
	private Node s;
	private Node t;
	private NodeArrayQueue2 queue;
	
	public EdmondsKarp(){
		graphic=new Node[6][6];
		Node node0=new Node();
		node0.start=0;
		node0.end=0;
		graphic[0][0]=node0;
		Node node1=new Node();
		node1.start=1;
		node1.end=1;
		graphic[1][1]=node1;
		Node node2=new Node();
		node2.start=2;
		node2.end=2;
		graphic[2][2]=node2;
		Node node3=new Node();
		node3.start=3;
		node3.end=3;
		graphic[3][3]=node3;
		Node node4=new Node();
		node4.start=4;
		node4.end=4;
		graphic[4][4]=node4;
		Node node5=new Node();
		node5.start=5;
		node5.end=5;
		graphic[5][5]=node5;
		Node node01=new Node();
		node01.c=16;
		node01.start=0;
		node01.end=1;
		graphic[0][1]=node01;
		Node node10=new Node();
		node10.start=1;
		node10.end=0;
		node10.reverse=true;
		graphic[1][0]=node10;
		Node node02=new Node();
		node02.c=13;
		node02.start=0;
		node02.end=2;
		graphic[0][2]=node02;
		Node node20=new Node();
		node20.start=2;
		node20.end=0;
		node20.reverse=true;
		graphic[2][0]=node20;
		Node node13=new Node();
		node13.c=12;
		node13.start=1;
		node13.end=3;
		graphic[1][3]=node13;
		Node node31=new Node();
		node31.start=3;
		node31.end=1;
		node31.reverse=true;
		graphic[3][1]=node31;
		Node node21=new Node();
		node21.c=4;
		node21.start=2;
		node21.end=1;
		graphic[2][1]=node21;
		Node node12=new Node();
		node12.start=1;
		node12.end=2;
		node12.reverse=true;
		graphic[1][2]=node12;
		Node node24=new Node();
		node24.start=2;
		node24.end=4;
		node24.c=14;
		graphic[2][4]=node24;
		Node node42=new Node();
		node42.start=4;
		node42.end=2;
		node42.reverse=true;
		graphic[4][2]=node42;
		Node node32=new Node();
		node32.c=9;
		node32.start=3;
		node32.end=2;
		graphic[3][2]=node32;
		Node node23=new Node();
		node23.start=2;
		node23.end=3;
		node23.reverse=true;
		graphic[2][3]=node23;
		Node node35=new Node();
		node35.c=20;
		node35.start=3;
		node35.end=5;
		graphic[3][5]=node35;
		Node node53=new Node();
		node53.start=5;
		node53.end=3;
		node53.reverse=true;
		graphic[5][3]=node53;
		Node node43=new Node();
		node43.c=7;
		node43.start=4;
		node43.end=3;
		graphic[4][3]=node43;
		Node node34=new Node();
		node34.start=3;
		node34.end=4;
		node34.reverse=true;
		graphic[3][4]=node34;
		Node node45=new Node();
		node45.c=4;
		node45.start=4;
		node45.end=5;
		graphic[4][5]=node45;
		Node node54=new Node();
		node54.start=5;
		node54.end=4;
		node54.reverse=true;
		graphic[5][4]=node54;
		
		s=graphic[0][0];
		t=graphic[5][5];
		queue = new NodeArrayQueue2((6 * (6 - 1) / 2) + 5);
		
	}
	
	public void edmondsKarp()throws Exception{
		broadFirstSearch();
		while(t.parent!=null){
			Node p=t;
			Node end=t;
			Node start=t.parent;
			int maxF=Integer.MAX_VALUE;
			while(p.parent!=null){
				Node edge=graphic[start.start][end.start];
				if(!edge.reverse){
					maxF=Math.min(maxF, edge.c-edge.f);
				}else{
					maxF=Math.min(maxF, edge.c-edge.fr);
				}
				p=end.parent;
				end=p;
				start=p.parent;
				
			}
			 p=t;
			 end=t;
			 start=t.parent;
			 while(p.parent!=null){
				 Node edge=graphic[start.start][end.start];
				 if(!edge.reverse){
					 edge.f=edge.f+maxF;
				 }else{
					 edge.fr=edge.fr+maxF;
				 }
				 p=end.parent;
				 end=p;
				 start=p.parent;
			 } 
			 t.parent=null;
			 broadFirstSearch();
		}
	}
	
	public void broadFirstSearch() throws Exception {
		for(int i=0;i<graphic.length;i++){
			for(int j=0;j<graphic.length;j++){
				if(graphic[i][j]!=null){
					graphic[i][j].color=Node.WHITE;
					graphic[i][j].parent=null;
				}
			}
		}
		s.color = Node.GRAY;
		s.d = 0;
		queue.enqueue(s);
		while (!queue.isEmpty()) {
			Node u = queue.dequeue();
			Node prev = u;
			for(int i=0;i<graphic.length;i++){
				Node v = graphic[u.start][i];
				if (v != null) {
					if (graphic[v.end][v.end].color == Node.WHITE) {
						if(v.c-v.f!=0&&!v.reverse){
							queue.enqueue(graphic[v.end][v.end]);
							graphic[v.end][v.end].parent = prev;
							graphic[v.end][v.end].color = Node.GRAY;
							graphic[v.end][v.end].d = prev.d + 1;
						}
						if(v.reverse&&v.fr-v.c<0){
							queue.enqueue(graphic[v.end][v.end]);
							graphic[v.end][v.end].parent = prev;
							graphic[v.end][v.end].color = Node.GRAY;
							graphic[v.end][v.end].d = prev.d + 1;
						}
					}
				}
			}
			u.color = Node.BLACK;
		}
	}
	public void printResult(){
		int result=0;
		for(int i=0;i<graphic.length;i++){
			if(graphic[t.start][i]!=null){
				result+=graphic[i][t.start].f;
			}
		}
		System.out.println("max flow:"+result);
	}
	
	public void print(){
		for(int i=0;i<graphic.length;i++){
			for(int j=0;j<graphic.length;j++){
				if(graphic[i][j]!=null){
					System.out.print(graphic[i][j].c+" ");
				}else{
					System.out.print("  ");
				}
			}
			System.out.println();
		}
	}
	private class Node{
		public static final int WHITE = 1;
		public static final int BLACK = 2;
		public static final int GRAY = 3;
		private int color = WHITE;
		private int c;
		private int f;
		private int fr;
		private int start;
		private int end;
		private int d=Integer.MAX_VALUE;;
		private Node parent;
		private boolean reverse;
	}
	class NodeArrayQueue2 {
		private Node[] data;
		private int head;
		private int tail;
		private boolean full;

		public NodeArrayQueue2(int size) {
			data = new Node[size];
			head = 0;
			tail = 0;
		}

		public void enqueue(Node d) throws Exception {
			if (head - tail == 0 && full || (head == 0 && (tail == 0) && full)) {
				throw new Exception("full");
			}
			data[tail] = d;
			tail = tail + 1;
			if (tail == data.length) {
				tail = 0;
			}
			if (head == tail) {
				full = true;
			}

		}

		public Node dequeue() throws Exception {
			if (head == tail && !full || (head == data.length && tail == 0)) {
				throw new Exception("empty");
			}
			full = false;
			head = head + 1;
			if (head == data.length) {
				head = 0;
				return data[data.length - 1];
			} else {
				return data[head - 1];
			}

		}

		public boolean isEmpty() {
			if (head == tail && !full || (head == data.length && tail == 0)) {
				return true;
			} else {
				return false;
			}
		}

	}
	public static void main(String[] args)throws Exception {
		EdmondsKarp e=new EdmondsKarp();
		e.print();
		e.edmondsKarp();
		e.printResult();

	}

}



相關推薦

-EdmondsKarp方法

package com.data.struct; public class EdmondsKarp { private Node[][]graphic; private Node s; private Node t; private NodeArrayQueu

HDU3605: Escape-二進制優化建-

tro 分享 strong to do truct void 最大流 cst star 目錄 目錄 思路: (有任何問題歡迎留言或私聊 && 歡迎交流討論哦 目錄 題意:傳送門 ?原題目描述在最下面。 ?\(n(n\leq 100000)\)個人\(m

HDU 4280 Island Transport(無向

clear ofa pri img size http algorithm caller end HDU 4280:http://acm.hdu.edu.cn/showproblem.php?pid=4280 題意:   比較裸的最大流題目,就是這是個無向圖,並且比較卡

3081 Marriage Match II 二分++並查集

題目連結 題意:n個女孩和n個男孩,每個女孩可以和沒有吵架過的或者是沒有和女孩的朋友吵架過的男孩配對,每輪遊戲女孩配對的男孩不能重複,求最多能進行幾輪遊戲。 思路:匹配問題,對於單輪遊戲來說就是求最大匹配了,但是對於多輪遊戲,每個女孩可以匹配多個男孩,又確定了答案的上下界

洛谷4400 BlueMary的旅行(分層+

qwq 首先,我們觀察到題目中提到的每天只能乘坐一次航班的限制,很容易想到建分層圖,也就是通過列舉天數,然後每天加入一層新的點。 (然而我一開始想的卻是erf) 考慮從小到大列舉天數,然後每次新建一層。 首先我們先讓

淺談求解方法

主要參考:  《演算法導論》 引言 還是前幾天參加的2014阿里巴巴春季校招(測試開發崗)筆試. 有道選擇題:   圖1中標出了每條有向公路最大流量,請問從S到T最大流量是( ).      A.46     B. 47     C. 54      D.77  

【網路24題】試題庫(二分+

傳送門     試題庫 I think     點集x,y分別放置試題與型別。源點向x集點連容量為1的邊,x集點向y中其所屬型別連容量為1的邊,y集點向T連容量為所需量的邊,求解最大流若等於總題數

-前置推送標籤方法

package com.data.struct; public class RelabelToFront { private Node[][]graphic; private Node s; private Node t; public RelabelToFr

【網路24題之一】飛行員配對問題+方案(網路dinic演算法二分匹配)

題面 題目背景 第二次世界大戰時期.. 題目描述 英國皇家空軍從淪陷國徵募了大量外籍飛行員。由皇家空軍派出的每一架飛機都需要配備在航行技能和語言上能互相配合的2 名飛行員,其中1 名是英國飛行員,另1名是外籍飛行員。在眾多的飛行員中,每一名外籍飛行員都可

的匹配問題與問題(二)——問題Ford-Fulkerson方法

本篇承接上一篇文章,主要講解最大流問題的Ford-Fulkerson解法。可是說這是一種方法,而不是演算法,因為它包含具有不同執行時間的幾種實現。該方法依賴於三種重要思想:殘留網路,增廣路徑和割。本文將會詳細介紹這些內容,下一篇文章我們提供一種該方法的Java實現。 在介紹

POJ2584_T-Shirt Gumbo(二分多重匹配/)

make sdn iss ... spa scanf ams ipp char s 解題報告 http://blog.csdn.net/juncoder/article/details/38239367 題目傳送門 題意: X個參賽選手,每一個選手有衣服

poj3680 Intervals 區間k覆蓋問題 小費用巧妙

全部 cstring ras 如果 cos printf als lld map /** 題目:poj3680 Intervals 區間k覆蓋問題 最小費用最大流 建圖巧妙 鏈接:http://poj.org/problem?id=3680 題意:給定n個區間,每個區間(

hdu4106 區間k覆蓋問題(連續m個數,多選k個數) 小費用巧妙

編號 blog .cn cstring 題意 acm 不同 本質 span /** 題目:hdu4106 區間k覆蓋問題(連續m個數,最多選k個數) 最小費用最大流 建圖巧妙 鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=410

POJ 1815 - Friendship - [拆點小點割集][暴力枚舉升序割點] - [Dinic算法模板 - 鄰接矩陣型]

ica exc otherwise 枚舉 cstring hat blog things input 妖怪題目,做到現在:2017/8/19 - 1:41…… 不過想想還是值得的,至少鄰接矩陣型的Dinic算法模板get√ 題目鏈接:http://poj.org/probl

刷題總結——太空飛行計劃(大權閉合子解決)

.com freopen static 出發 pre nbsp 資料 任務 代碼 題目: 題目描述 W 教授正在為國家航天中心計劃一系列的太空飛行。每次太空飛行可進行一系列商業性實驗而獲取利潤。現已確定了一個可供選擇的實驗集合 E={E1,E2,…,Em},和進行這些實驗

POJ A Plug for UNIX ()

建圖 inter tel != 不能 which mic ios ber Description You are in charge of setting up the press room for the inaugural meeting of the United N

51nod 2006 飛行員配對(二分匹配) 裸匈牙利算法 二分匹配題

spa 解法 tor != cto == 遇到 由於 include 題目: 題目已經說了是最大二分匹配題, 查了一下最大二分匹配題有兩種解法, 匈牙利算法和網絡流。 看了一下覺得匈牙利算法更好理解, 然後我照著小紅書模板打了一遍就過了。 匈牙利算法:先試

POJ2289 Jamie's Contact Groups —— 二分多重匹配/ + 二分

u+ letter appears i++ ive desc target ups tro 題目鏈接:https://vjudge.net/problem/POJ-2289 Jamie‘s Contact Groups Time Limit: 7000MS

POJ2112 Optimal Milking —— 二分多重匹配/ + 二分

題目 none utili cnblogs tell pac log head star 題目鏈接:https://vjudge.net/problem/POJ-2112 Optimal Milking Time Limit: 2000MS Memory L

POJ3189 Steady Cow Assignment —— 二分多重匹配/ + 二分

next cows int find ebr including top miss -s 題目鏈接:https://vjudge.net/problem/POJ-3189 Steady Cow Assignment Time Limit: 1000MS Me