Expm 10_2 实现Ford-Fulkerson算法,求出给定图中从源点s到汇点t的最大流,并输出最小割。
package org.xiu68.exp.exp10; import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays; public class Exp10_2 {
//实现Ford-Fulkerson算法,求出给定图中从源点s到汇点t的最大流,并输出最小割。
public static void main(String[] args) {
// TODO Auto-generated method stub
int[][] c=new int[][]{
{0,1,1,0},
{0,0,1,1},
{0,0,0,1},
{0,0,0,0}
};
MGraph1 m1=new MGraph1(c);
m1.fordFulkerson(0, 3); int[][] c1=new int[][]{
{0,3,3,4,0,0,0},
{0,0,0,0,2,0,0},
{0,1,0,0,1,0,0},
{0,0,0,0,0,5,0},
{0,0,0,1,0,1,2},
{0,0,0,0,0,0,5},
{0,0,0,0,0,0,0}
};
MGraph1 m2=new MGraph1(c1);
m2.fordFulkerson(0, 6);
}
} class MGraph1{
private int[][] c; //容量矩阵
private int[][] e; //残量矩阵
private int[][] f; //当前流矩阵
private int vexNum; //顶点数量 public MGraph1(int[][] c){
this.c=c;
this.vexNum=c.length;
this.e=new int[vexNum][vexNum];
this.f=new int[vexNum][vexNum]; //刚开始时残量矩阵等于容量矩阵
for(int i=0;i<vexNum;i++){
System.arraycopy(c[i], 0, e[i], 0, c[i].length);
} }
//fordFulkerson算法
public void fordFulkerson(int s,int t){
int[] route=new int[vexNum]; //s到t的路径数组,route[i]表示i的前一个顶点 while(bfs(s,t,route)){ //若还能找到一条路径 //寻找路径中流最小的边的大小(在残量矩阵中)
int min=Integer.MAX_VALUE;
int tail=t;
int head=route[t]; while(head!=-1){
if(e[head][tail]<min){
min=e[head][tail];
}
tail=head;
head=route[head];
} //更新当前流矩阵和残量矩阵
int tail1=t;
int head1=route[tail1];
while(head1!=-1){
//更新当前流矩阵
if(c[head1][tail1]!=0){
f[head1][tail1]+=min; //容量矩阵中存在边,增加head1到tail1的流的大小为min
}else{
f[head1][tail1]-=min; //容量矩阵中不存在边,撤销head1到tail1的流的大小为min
}
//更新残量矩阵
e[head1][tail1]-=min; //head1到tail1的流量减少min
e[tail1][head1]+=min; //tail1到head1的流量增加min tail1=head1;
head1=route[head1];
}//while
//route=new int[vexNum];
Arrays.fill(route, 0); //初始化路径数组
}//while 还能找到一条s到t的路径 int maxFlow=0;
for(int i=0;i<vexNum;i++) //最大流为 当前流矩阵中 从s流出的量
maxFlow+=f[s][i];
System.out.println("最大流为:"+maxFlow); System.out.print("最小割为(集合S):");
ArrayList<Integer> cut=cut(s);
for(int i=0;i<cut.size();i++)
System.out.print(cut.get(i)+" ");
System.out.println(); } //广度优先搜索在残量图e中寻找s到t的路径
public boolean bfs(int s,int t,int[] route){
boolean[] visited=new boolean[vexNum]; //访问数组
visited[s]=true; ArrayDeque<Integer> queue=new ArrayDeque<>();
route[s]=-1; //设s的前一个顶点为-1 for(int i=0;i<vexNum;i++){
if(e[s][i]!=0 && !visited[i]){ //在残量矩阵中s到i存在一条路径
queue.add(i);
route[i]=s;
visited[i]=true;
}
} while(!queue.isEmpty()){
int middleVex=queue.poll();
if(middleVex==t){
return true;
}else{
for(int i=0;i<vexNum;i++){
if(e[middleVex][i]!=0 && !visited[i]){
queue.add(i);
route[i]=middleVex;
visited[i]=true;
}
}
}
}//while
return false;
} //求最小割
//在残量矩阵中,从s开始做一次搜索,从s能达到的所有的顶点都属于集合S
public ArrayList<Integer> cut(int s){
boolean[] visited=new boolean[vexNum];
ArrayList<Integer> cut=new ArrayList<>(); //保存最小割,集合S
dfs(visited,cut,s);
return cut;
}
//深度优先搜索
private void dfs(boolean[] visited,ArrayList<Integer> cut,int v){
cut.add(v);
visited[v]=true;
for(int i=0;i<vexNum;i++){
if(e[v][i]!=0 && !visited[i]){
dfs(visited,cut,i);
}
}
}
}
Expm 10_2 实现Ford-Fulkerson算法,求出给定图中从源点s到汇点t的最大流,并输出最小割。的更多相关文章
- Tarjan算法求出强连通分量(包含若干个节点)
[功能] Tarjan算法的用途之一是,求一个有向图G=(V,E)里极大强连通分量.强连通分量是指有向图G里顶点间能互相到达的子图.而如果一个强连通分量已经没有被其它强通分量完全包含的话,那么这个强连 ...
- Java算法——求出两个字符串的最长公共字符串
问题:有两个字符串str1和str2,求出两个字符串中最长公共字符串. 例如:“acbbsdef”和"abbsced"的最长公共字符串是“bbs” 算法思路: 1.把两个字符串分别 ...
- hdu 1217 利用flord算法求 有环图 2点之间最大值
Arbitrage T ime Limit: 2000/1000 MS (Java/Other ...
- 有一个array的数组,长度为10000,大小不一,用算法找出该数组中的最大值。
不用算法的答案是: var a=[1,2,3,5……];alert(Math.max.apply(null, a));//最大值alert(Math.min.apply(null, a));//最 ...
- 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007
include "stdafx.h" #include<iostream> #include<vector> #include <algorithm& ...
- 使用Java语言实现,自己主动生成10个整数(1~100,求出生成数列中的最大值和最小值,不同意使用Arrays类的sort方法
这是考察主要的java基础,没啥难点,直接上代码,近期在准备面试,所以做一些基础的面试题练练手 public class Demo1 { public static void main(String[ ...
- AcWing 858. Prim算法求最小生成树 稀疏图
//稀疏图 #include <cstring> #include <iostream> #include <algorithm> using namespace ...
- AcWing 859. Kruskal算法求最小生成树 稠密图
//稠密图 #include <cstring> #include <iostream> #include <algorithm> using namespace ...
- dijskra算法(求正权图中最短路)
思想:每次找到离原点最近的顶点,以这个点为中心扩展松弛,更新其余点到原点的最短路径. 注意:if(e[u][v]>x)e[u][v]=x; book[ ]数组标记最短路程的顶点集合 #inclu ...
随机推荐
- 利用C#访问注册表获取软件的安装路径
文章地址:https://blog.csdn.net/yl2isoft/article/details/17332139
- React Native的语法之ES5和ES6
原文地址:http://www.devio.org/2016/08/11/React-Native%E4%B9%8BReact%E9%80%9F%E5%AD%A6%E6%95%99%E7%A8%8B- ...
- SpringBoot系列: Json的序列化和反序列化
============================= 控制 json 序列化/反序列化=============================1. @JsonIgnoreProperties的 ...
- Spring整合redis配置文件详解
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...
- 2.4 if-else
if-else 想一想:在使用if的时候,它只能做到满足条件时要做的事情.那万一需要在不满足条件的时候,做某些事,该怎么办呢? 答:使用 if-else <1>if-else的使用格式 i ...
- rabbitMQ学习1:消息队列介绍与rabbitmq安装使用
1. 什么是消息队列 生活里的消息队列,如同邮局的邮箱, 如果没邮箱的话, 邮件必须找到邮件那个人,递给他,才玩完成,那这个任务会处理的很麻烦,很慢,效率很低 但是如果有了邮箱, 邮件直接丢给邮箱,用 ...
- day 10 - 2 函数练习
1.写函数 接收 n 个数字 求这些参数数字的和 def sum_func(*args): total = 0 for i in args: total += i return total prin ...
- HDFS笔记(二)
fsimage : NameNode启动时,对文件系统的快照 eidt logs : NameNode启动后,对文件系统的改动序列 namenode在全局里就一个进程,所以存在单点问题 DataNod ...
- GB GBRT XgBoost
https://blog.csdn.net/github_38414650/article/details/76061893 https://www.cnblogs.com/wxquare/p/554 ...
- shell编程 之 echo命令和printf命令
1 echo命令基本情况: echo显示普通字符:echo "i am studying shell"(有木有引号都可以) 支持转义字符:echo "\"hel ...