Java实现最小费用最大流问题
1 问题描述
在最大流有多组解时,给每条边在附上一个单位费用的量,问在满足最大流时的最小费用是多少?
2 解决方案
下面代码所使用的测试数据如下图:

package com.liuzhen.practice;
import java.util.ArrayList;
import java.util.Scanner;
public class Main {
public static int MAX = 1000;
public static int n; //图中顶点数目
public static boolean[] used = new boolean[MAX]; //判断顶点是否在队列中
public static int[] pre = new int[MAX]; //记录最短增广路径中相应节点的前节点
public static int[] distance = new int[MAX]; //记录源点到图中其他所有顶点的最短距离
public static int[] capacity = new int[MAX]; //用于记录遍历图每一次得到增广路径的流量
public static ArrayList<edge>[] map; //图的邻接表
//表示图中边信息内部类
static class edge {
public int from; //边的起点
public int to; //边的终点
public int cap; //边的容量
public int cost; //边的费用
public edge(int from, int to, int cap, int cost) {
this.from = from;
this.to = to;
this.cap = cap;
this.cost = cost;
}
}
//输入给定图数据
@SuppressWarnings("unchecked")
public void init() {
Scanner in = new Scanner(System.in);
n = in.nextInt();
int k = in.nextInt(); //给定图的边数目
map = new ArrayList[n];
for(int i = 0;i < n;i++)
map[i] = new ArrayList<edge>();
for(int i = 0;i < k;i++) {
int from = in.nextInt();
int to = in.nextInt();
int cap = in.nextInt();
int cost = in.nextInt();
map[from].add(new edge(from, to, cap, cost)); //正向边
map[to].add(new edge(to, from, 0, -cost)); //反向边
}
}
//寻找顶点start到顶点end的最短路径(PS:即费用最少的一条增广路径)
public boolean spfa(int start, int end) {
int[] count = new int[n];
for(int i = 0;i < n;i++) {
used[i] = false;
pre[i] = -1;
distance[i] = Integer.MAX_VALUE;
capacity[i] = Integer.MAX_VALUE;
}
used[start] = true;
pre[start] = start;
distance[start] = 0;
count[start]++;
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(start);
while(!list.isEmpty()) {
int index = list.get(0);
list.remove(0);
used[index] = false;
for(int i = 0;i < map[index].size();i++) {
edge temp = map[index].get(i);
if(temp.cap > 0 && distance[temp.to] > distance[index] + temp.cost) {
//记录顶点start到图中其它顶点之间的最短费用距离
distance[temp.to] = distance[index] + temp.cost;
pre[temp.to] = index;
//记录增广路径能够流通的最大流量
capacity[temp.to] = Math.min(capacity[index], temp.cap);
if(!used[temp.to]) {
used[temp.to] = true;
list.add(temp.to);
count[temp.to]++;
if(count[temp.to] > n) //用于判断图中是否有负环
return false;
}
}
}
}
if(distance[end] != Integer.MAX_VALUE && pre[end] != -1)
return true;
return false;
}
public int getResult() {
init(); //输入给定图数据
int minCost = 0;
int start = 0; //把源点设置为顶点0
int end = n - 1; //把汇点设置为顶点n - 1
while(true) {
if(spfa(start, end) == false)
break;
System.out.println("增广路径增量:"+capacity[end]+", 费用流:"+distance[end]);
minCost += distance[end] * capacity[end];
int last = end;
int begin = end;
System.out.print("汇点出发");
while(begin != start) {
last = begin;
begin = pre[last];
int i = 0, j = 0;
System.out.print("——>"+last);
for(;i < map[begin].size();i++) {
if(map[begin].get(i).to == last)
break;
}
map[begin].get(i).cap -= capacity[end]; //正向边剩余流量减少
for(;j < map[last].size();j++) {
if(map[last].get(j).to == begin)
break;
}
map[last].get(j).cap += capacity[end]; //反向边剩余流量增加
}
System.out.println("——>"+begin);
}
return minCost;
}
public static void main(String[] args) {
Main test = new Main();
int result = test.getResult();
System.out.println(result);
}
}
运行结果:
7
1 2 1
3 3 2
2 5 5
4 3 4
5 2 10
2 1 3
5 4 7
增广路径增量:2, 费用流:12
汇点出发——>5——>4——>1——>0
增广路径增量:1, 费用流:15
汇点出发——>5——>2——>3——>0
Java实现最小费用最大流问题的更多相关文章
- 算法笔记_140:最小费用最大流问题(Java)
目录 1 问题描述 2 解决方案 1 问题描述 在最大流有多组解时,给每条边在附上一个单位费用的量,问在满足最大流时的最小费用是多少? 2 解决方案 下面代码所使用的测试数据如下图: 具体代码如下 ...
- poj3422 Kaka's Matrix Travels(最小费用最大流问题)
/* poj3422 Kaka's Matrix Travels 不知道 k次 dp做为什么不对??? 看了大牛的代码,才知道还可以这样做! 开始没有理解将a 和 a‘ 之间建立怎样的两条边,导致程序 ...
- hdu 2686最小费用最大流问题
#include<stdio.h> #include<queue> #include<string.h> using namespace std; #define ...
- ACM/ICPC 之 卡卡的矩阵旅行-最小费用最大流(可做模板)(POJ3422)
将每个点拆分成原点A与伪点B,A->B有两条单向路(邻接表实现时需要建立一条反向的空边,并保证环路费用和为0),一条残留容量为1,费用为本身的负值(便于计算最短路),另一条残留容量+∞,费用为0 ...
- Going Home(最小费用最大流)
Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 16200 Accepted: 8283 Description On a ...
- HIT 2715 - Matrix3 - [最小费用最大流][数组模拟邻接表MCMF模板]
题目链接:http://acm.hit.edu.cn/hoj/problem/view?id=2715 Time limit : 5 sec Memory limit : 64 M Zhouguyue ...
- POJ-2159 最小费用最大流
Going Home 自己写的第一道费用流,图建好一波板子AC.不过还是有几个地方有点迷. 先来 ...
- POJ2516 Minimum Cost —— 最小费用最大流
题目链接:https://vjudge.net/problem/POJ-2516 Minimum Cost Time Limit: 4000MS Memory Limit: 65536K Tota ...
- poj 2135最小费用最大流
最小费用最大流问题是经济学和管理学中的一类典型问题.在一个网络中每段路径都有"容量"和"费用"两个限制的条件下,此类问题的研究试图寻找出:流量从A到B,如何选择 ...
随机推荐
- {path:“ /”,expires:7}这一段是什么意思?
1.创建会话cookie: $ .cookie('name','value'); 2.创建到期的cookie,然后7天: $ .cookie('name','value',{到期日:7}); 3.创建 ...
- 宝塔webHook自动同步代码的使用
#!/bin/bashecho ""#输出当前时间date --date='0 days ago' "+%Y-%m-%d %H:%M:%S"echo " ...
- JQuery踩过的坑,遇到就记下
1 乱用选择器 坑人指数:200 JQuery选择器调用代价很大,反复调用效率更低.应采用缓存对象的方法或采用链式调用的方式. //错误的写法 $("#button").click ...
- 不吹牛X,我真的干掉了if-else
我们在web开发中,经常使用数据库表中的字段作为"标记"来表示多个"状态",比如: 我们就以某宝的在线购物流程为例进行分析.在订单表中,使用zt字段来表示定单的 ...
- kibana 通过nginx+ldap实现登录认证
nginx配置 使用自己搭建的openldap 使用用户中心的openldap
- 使用naxsi
naxsi简介 naxsi 是一个nginx 防病毒,防跨站,sql 注入的一个模块.nginx的一个waf ,应用防火墙.非常好配置. naxsi 安装 naxsi 在debina/ubuntu 上 ...
- 「雕爷学编程」Arduino动手做(35)——模拟量声音传感器
37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止37种的.鉴于本人手头积累了一些传感器和模块,依照实践出真知(一定要动手做)的理念,以学习和交流为目的,这里 ...
- webpack指南(四)shimming
shimming 将一个新的 API 引入到一个旧的环境中,而且仅靠旧的环境中已有的手段实现. ProvidePlugin 我们在程序中暴露一个变量,通知webpack某个库被使用,webpack将在 ...
- XShell 评估到期
刚刚打开XShell弹出”评估到期“,点击确定后自动打开中文官网,得购买后才能使用. 当初下载的时候没留意到会有这一天.. 手头拮据的朋友可以通过下面方法绕过: 删除XShell. 到英文官网下载页找 ...
- vue绑定数据之前 会看到源代码
http://blog.csdn.net/fengjingyu168/article/details/72915468 VUE绑定数据闪现问题 问题描述如下: 1.在HTML中使用Vue为div绑定数 ...