zoukankan      html  css  js  c++  java
  • Expm 10_2 实现Ford-Fulkerson算法,求出给定图中从源点s到汇点t的最大流,并输出最小割。

      1 package org.xiu68.exp.exp10;
      2 
      3 import java.util.ArrayDeque;
      4 import java.util.ArrayList;
      5 import java.util.Arrays;
      6 
      7 public class Exp10_2 {
      8     //实现Ford-Fulkerson算法,求出给定图中从源点s到汇点t的最大流,并输出最小割。
      9     public static void main(String[] args) {
     10         // TODO Auto-generated method stub
     11         int[][] c=new int[][]{
     12             {0,1,1,0},
     13             {0,0,1,1},
     14             {0,0,0,1},
     15             {0,0,0,0}
     16         };
     17         MGraph1 m1=new MGraph1(c);
     18         m1.fordFulkerson(0, 3);
     19 
     20         int[][] c1=new int[][]{
     21             {0,3,3,4,0,0,0},
     22             {0,0,0,0,2,0,0},
     23             {0,1,0,0,1,0,0},
     24             {0,0,0,0,0,5,0},
     25             {0,0,0,1,0,1,2},
     26             {0,0,0,0,0,0,5},
     27             {0,0,0,0,0,0,0}
     28         };
     29         MGraph1 m2=new MGraph1(c1);
     30         m2.fordFulkerson(0, 6);
     31     }
     32 }
     33 
     34 class MGraph1{
     35     private int[][] c;        //容量矩阵
     36     private int[][] e;        //残量矩阵
     37     private int[][] f;        //当前流矩阵
     38     private int vexNum;        //顶点数量
     39     
     40     public MGraph1(int[][] c){
     41         this.c=c;
     42         this.vexNum=c.length;
     43         this.e=new int[vexNum][vexNum];
     44         this.f=new int[vexNum][vexNum];
     45 
     46         //刚开始时残量矩阵等于容量矩阵
     47         for(int i=0;i<vexNum;i++){
     48             System.arraycopy(c[i], 0, e[i], 0, c[i].length);
     49         }
     50         
     51     }
     52     //fordFulkerson算法
     53     public void fordFulkerson(int s,int t){
     54         int[] route=new int[vexNum];    //s到t的路径数组,route[i]表示i的前一个顶点
     55         
     56         while(bfs(s,t,route)){             //若还能找到一条路径
     57             
     58             //寻找路径中流最小的边的大小(在残量矩阵中)
     59             int min=Integer.MAX_VALUE;
     60             int tail=t;
     61             int head=route[t];
     62 
     63             while(head!=-1){
     64                 if(e[head][tail]<min){
     65                     min=e[head][tail];
     66                 }
     67                 tail=head;
     68                 head=route[head];
     69             }        
     70             
     71             //更新当前流矩阵和残量矩阵
     72             int tail1=t;
     73             int head1=route[tail1];
     74             while(head1!=-1){
     75                 //更新当前流矩阵
     76                 if(c[head1][tail1]!=0){        
     77                     f[head1][tail1]+=min;        //容量矩阵中存在边,增加head1到tail1的流的大小为min
     78                 }else{
     79                     f[head1][tail1]-=min;        //容量矩阵中不存在边,撤销head1到tail1的流的大小为min
     80                 }
     81                 //更新残量矩阵
     82                 e[head1][tail1]-=min;            //head1到tail1的流量减少min
     83                 e[tail1][head1]+=min;            //tail1到head1的流量增加min
     84                 
     85                 tail1=head1;
     86                 head1=route[head1];
     87             }//while
     88             //route=new int[vexNum];
     89             Arrays.fill(route, 0);                 //初始化路径数组
     90         }//while 还能找到一条s到t的路径
     91         
     92         int maxFlow=0;
     93         for(int i=0;i<vexNum;i++)                //最大流为  当前流矩阵中  从s流出的量
     94             maxFlow+=f[s][i];
     95         System.out.println("最大流为:"+maxFlow);
     96         
     97         
     98         System.out.print("最小割为(集合S):");
     99         ArrayList<Integer> cut=cut(s);
    100         for(int i=0;i<cut.size();i++)
    101             System.out.print(cut.get(i)+" ");
    102         System.out.println();
    103         
    104     }
    105     
    106     //广度优先搜索在残量图e中寻找s到t的路径
    107     public boolean bfs(int s,int t,int[] route){
    108         boolean[] visited=new boolean[vexNum];        //访问数组
    109         visited[s]=true;
    110         
    111         ArrayDeque<Integer> queue=new ArrayDeque<>();
    112         route[s]=-1;                                //设s的前一个顶点为-1
    113         
    114         for(int i=0;i<vexNum;i++){
    115             if(e[s][i]!=0 && !visited[i]){            //在残量矩阵中s到i存在一条路径
    116                 queue.add(i);
    117                 route[i]=s;
    118                 visited[i]=true;
    119             }
    120         }
    121         
    122         while(!queue.isEmpty()){
    123             int middleVex=queue.poll();
    124             if(middleVex==t){
    125                 return true;
    126             }else{
    127                 for(int i=0;i<vexNum;i++){
    128                     if(e[middleVex][i]!=0 && !visited[i]){
    129                         queue.add(i);
    130                         route[i]=middleVex;
    131                         visited[i]=true;
    132                     }
    133                 }
    134             }
    135         }//while
    136         return false;
    137     }
    138     
    139     //求最小割
    140     //在残量矩阵中,从s开始做一次搜索,从s能达到的所有的顶点都属于集合S
    141     public ArrayList<Integer> cut(int s){
    142         boolean[] visited=new boolean[vexNum];
    143         ArrayList<Integer> cut=new ArrayList<>();    //保存最小割,集合S
    144         dfs(visited,cut,s);
    145         return cut;
    146     }
    147     //深度优先搜索
    148     private void dfs(boolean[] visited,ArrayList<Integer> cut,int v){
    149         cut.add(v);
    150         visited[v]=true;    
    151         for(int i=0;i<vexNum;i++){
    152             if(e[v][i]!=0 && !visited[i]){
    153                 dfs(visited,cut,i);
    154             }
    155         }
    156     }
    157 }
    View Code
  • 相关阅读:
    PHP的ip2long和long2ip函数的实现原理
    PHP在浏览器上跟踪调试的方法以及使用ChromePhp、FirePHP的简单介绍
    PHP静态延迟绑定简单示例
    [deviceone开发]-do_Socket组件示例
    [deviceone开发]-大家比较关注的应用内部升级
    [deviceone开发]-do_Viewshower的动画效果示例
    [deviceone开发]-企业OA项目开源分享
    [deviceone开发]-do_RichLabel的简单示例
    [deviceone开发]-直播APP心形点赞动画示例
    [deviceone开发]-纳豆项目源码开源
  • 原文地址:https://www.cnblogs.com/xiu68/p/8043674.html
Copyright © 2011-2022 走看看