最大流Ford-Fulkerson算法

阅读更多
算法导论对最大流算法有很详细的介绍,今天实现了最大流Ford-Fulkerson的算法,包括BFS和DFS来搜索增广路径。
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

public class MaxFlow
{

    private int capacity[][];
    private int flow[][];
    private boolean visited[];
    private int pre[];
    private int nodes;

    public MaxFlow( int[][] capacity, int nodes )
    {
        this.capacity = capacity;
        this.nodes = nodes;
        this.flow = new int[nodes][nodes];
        this.pre = new int[nodes];
        this.visited = new boolean[nodes];
    }

    public int maxFlow( int src, int des )
    {
        int maxFlow = 0;
        
        for( int i = 0; i < nodes; i++ )
            for( int j = 0; j < nodes; j++ )
                flow[i][j] = 0;

        while( true )//find a augment path
        {
            for( int i = 0; i < nodes; i++ )
            {
                visited[i] = false;
            }
            pre[src] = -1;
            
            if(!BFS( src, des )){// the BFS 
                break;
            }
            
            /*DFS(src,des);//DFS
            if(!visited[des])
                break;*/
            
            int increment = Integer.MAX_VALUE;
            for( int i = des; pre[i] >= src; i = pre[i] )
            {
                //find the min flow of the path
                increment = Math.min( increment, capacity[pre[i]][i]
                        - flow[pre[i]][i] );
            }
            
            //update the flow
            for( int i = des; pre[i] >= src; i = pre[i] )
            {
                flow[pre[i]][i] += increment;
                flow[i][pre[i]] -= increment;
            }
            //increase the maxFow with the increment 
            maxFlow += increment;
        }
        return maxFlow;
    }

    private void DFS(int src, int des){
        visited[src] = true;
        for(int i = 0; i < nodes; i++){
            if(!visited[i] && ( capacity[src][i] - flow[src][i] > 0) ){
                pre[i] = src;//record the augment path
                visited[i] = true;
                DFS(i,des);
            }
        }
    }
    
    private boolean BFS( int src, int des )
    {
        Queue queue = new LinkedList();
        queue.add( src );
        visited[src] = true;
        while( !queue.isEmpty() )
        {
            int node = queue.poll();
            for( int i = 0; i < nodes; i++ )
            {
                if( !visited[i] && (capacity[node][i] - flow[node][i] > 0) )
                {
                    queue.add( i );
                    visited[i] = true;
                    pre[i] = node;//record the augment path
                }
            }
        }

        return visited[des];
    }

    public static void main( String[] args )
    {

        int nodes, edges;
        Scanner scanner = new Scanner( System.in );
        
        nodes = scanner.nextInt();
        edges = scanner.nextInt();

        int[][] capacity = new int[nodes][nodes];

        int src, des, c;
        for( int i = 0; i < edges; i++ )
        {
            src = scanner.nextInt();
            des = scanner.nextInt();
            c = scanner.nextInt();
            capacity[src][des] = c;
        }

        MaxFlow maxFlow = new MaxFlow( capacity, nodes );
        System.out.println( maxFlow.maxFlow( 0, nodes - 1 ) );
    }
}


输入:
6 10    // 6 nodes, 10 edges
0 1 16  // capacity from 0 to 1 is 16
0 2 13  // capacity from 0 to 2 is 13
1 2 10  // capacity from 1 to 2 is 10
2 1 4   // capacity from 2 to 1 is 4
3 2 9   // capacity from 3 to 2 is 9
1 3 12  // capacity from 1 to 3 is 12
2 4 14  // capacity from 2 to 4 is 14
4 3 7   // capacity from 4 to 3 is 7
3 5 20  // capacity from 3 to 5 is 20
4 5 4   // capacity from 4 to 5 is 4
输出:
23

你可能感兴趣的:(算法,C,C++,C#,J#)