void addedge(int fr,int to,int cap,int cos){
sid[cnt].fr=fr;sid[cnt].des=to;sid[cnt].cap=cap;sid[cnt].cos=cos;sid[cnt].next=nd[fr];nd[fr]=cnt++;
sid[cnt].fr=to;sid[cnt].des=fr;sid[cnt].cap=;sid[cnt].cos=-cos;sid[cnt].next=nd[to];nd[to]=cnt++;
} int spfa(){
dl[head=tail=]=sor;
for (int i=;i<=n+;i++) dis[i]=1e9;
for (int i=;i<=n+;i++) b[i]=;
for (int i=;i<=n+;i++) count[i]=;
b[sor]=;
dis[sor]=;
while (head<=tail){
for (int p=nd[dl[head]];p!=-;p=sid[p].next)
if ((sid[p].cap!=)&&(dis[sid[p].des]>dis[dl[head]]+sid[p].cos)){
path[sid[p].des]=p;
if (b[sid[p].des]==){
dl[++tail]=sid[p].des;
b[sid[p].des]=;
count[sid[p].des]++;
}
dis[sid[p].des]=dis[dl[head]]+sid[p].cos;
}
b[dl[head++]]=;
} if (dis[tar]==1e9) return();else return();
} void aug(){
int po=tar,flow=1e9; while (po!=sor){
int p=path[po];
flow=min(flow,sid[p].cap);
po=sid[p].fr;
} po=tar; while (po!=sor){
int p=path[po];
sid[p].cap-=flow;
ans+=flow*sid[p].cos;
sid[p^].cap+=flow;
po=sid[p].fr;
}
}

最小费用最大流

uses math;

var
n,m,i,j :longint;
ans:int64;
dl:array[..] of longint;
cost,tcap,cap:array[..,..] of int64;
dis:array[..] of longint;
pre:array[..] of longint;
a,b:array[..] of longint;
c:Array[..,..] of longint; procedure build;
var
i,j:longint;
begin
for i:= to n do
begin
cap[,i]:=maxlongint;
cost[,i]:=;
end; for i:= to n do
begin
cap[i,i+n]:=a[i];
cost[i,i+n]:=;
end; for i:= to n do
for j:= to m do
begin
cap[i+n,j+*n]:=maxlongint;
cost[i+n,j+*n]:=c[i,j];
cost[j+*n,i+n]:=-c[i,j];
end; for i:= to m do
begin
cap[i+*n,i+*n+m]:=b[i];
cost[i+*n,i+*n+m]:=;
end; for i:= to m do
begin
cap[i+*n+m,*n+*m+]:=maxlongint;
cost[i+*n+m,*n+*m+]:=;
end;
end; procedure aug;
var
po:longint;
mi:int64;
pr:longint;
begin
po:=*n+*m+;
mi:=maxlongint;
while po<> do
begin
pr:=pre[po];
mi:=min(mi,tcap[pr,po]);
po:=pr;
end; po:=*n+*m+;
while po<> do
begin
pr:=pre[po];
dec(tcap[pr,po],mi);
inc(tcap[po,pr],mi);
inc(ans,mi*cost[pr,po]);
po:=pr;
end;
end; function spfa1:boolean;
var
i,head,tail,u:longint;
begin
for i:= to *m+*n+ do
dis[i]:=maxlongint;
dis[]:=; head:=;tail:=;
dl[]:=;
while head<=tail do
begin
u:=dl[head];
for i:= to *n+*m+ do
if (tcap[u,i]>) and (dis[i]>dis[u]+cost[u,i]) then
begin
pre[i]:=u;
inc(tail);
dl[tail]:=i;
dis[i]:=dis[u]+cost[u,i];
end;
inc(head);
end; if dis[*n+*m+]=maxlongint then exit(false) else exit(true);
end; begin read(n,m); for i:= to n do
read(a[i]);
for i:= to m do
read(b[i]);
for i:= to n do
for j:= to m do
read(c[i,j]); build; for i:= to *n+*m+ do
for j:= to *n+*m+ do
tcap[i,j]:=cap[i,j];
while spfa1 do aug;
writeln(ans); end.

最大费用最大流

uses math;

var
n,m,i,j :longint;
ans:int64;
dl:array[..] of longint;
cost,tcap,cap:array[..,..] of int64;
dis:array[..] of longint;
pre:array[..] of longint;
a,b:array[..] of longint;
c:Array[..,..] of longint; procedure build;
var
i,j:longint;
begin
for i:= to n do
begin
cap[,i]:=maxlongint;
cost[,i]:=;
end; for i:= to n do
begin
cap[i,i+n]:=a[i];
cost[i,i+n]:=;
end; for i:= to n do
for j:= to m do
begin
cap[i+n,j+*n]:=maxlongint;
cost[i+n,j+*n]:=c[i,j];
cost[j+*n,i+n]:=-c[i,j];
end; for i:= to m do
begin
cap[i+*n,i+*n+m]:=b[i];
cost[i+*n,i+*n+m]:=;
end; for i:= to m do
begin
cap[i+*n+m,*n+*m+]:=maxlongint;
cost[i+*n+m,*n+*m+]:=;
end;
end; procedure aug;
var
po:longint;
mi:int64;
pr:longint;
begin
po:=*n+*m+;
mi:=maxlongint;
while po<> do
begin
pr:=pre[po];
mi:=min(mi,tcap[pr,po]);
po:=pr;
end; po:=*n+*m+;
while po<> do
begin
pr:=pre[po];
dec(tcap[pr,po],mi);
inc(tcap[po,pr],mi);
inc(ans,mi*cost[pr,po]);
po:=pr;
end;
end; function spfa2:boolean;
var
i,u,head,tail:longint;
begin
for i:= to *m+*n+ do
dis[i]:=-maxlongint;
dis[]:=; head:=;tail:=;
dl[]:=;
while head<=tail do
begin
u:=dl[head];
for i:= to *n+*m+ do
if (tcap[u,i]>) and (dis[i]<dis[u]+cost[u,i]) then
begin
pre[i]:=u;
inc(tail);
dl[tail]:=i;
dis[i]:=dis[u]+cost[u,i];
end;
inc(head);
end; if dis[*n+*m+]=-maxlongint then exit(false) else exit(true);
end; begin read(n,m); for i:= to n do
read(a[i]);
for i:= to m do
read(b[i]);
for i:= to n do
for j:= to m do
read(c[i,j]); build; ans:=;
for i:= to *n+*m+ do
for j:= to *n+*m+ do
tcap[i,j]:=cap[i,j];
while spfa2 do aug;
writeln(ans); end.

边表模板

procedure addedge(u,v,cap,cost:longint);
begin
sid[tot].u:=u;
sid[tot].v:=v;
sid[tot].cap:=cap;
sid[tot].cost:=cost;
sid[tot].next:=nd[u];
nd[u]:=tot;
inc(tot);
sid[tot].u:=v;
sid[tot].v:=u;
sid[tot].cap:=;
sid[tot].cost:=-cost;
sid[tot].next:=nd[v];
nd[v]:=tot;
inc(tot);
end; function spfa:boolean;
var
i,head,tail,u,p:longint;
begin for i:= to n+ do dis[i]:=maxlongint div ;
for i:= to n+ do vis[i]:=true; head:=;tail:=;
dl[]:=;
while head<=tail do
begin
u:=dl[head];
p:=nd[dl[head]];
while p<>- do
begin
if (sid[p].cap>) and (dis[u]+sid[p].cost<dis[sid[p].v]) then
begin
if vis[sid[p].v]=true then
begin
inc(tail);
dl[tail]:=sid[p].v;
vis[sid[p].v]:=false;
end;
pre[sid[p].v]:=p;
dis[sid[p].v]:=dis[u]+sid[p].cost;
end;
p:=sid[p].next;
end;
vis[dl[head]]:=true;
inc(head);
end; if dis[n+]=maxlongint div then exit(false) else exit(true);
end; procedure aug;
var
po,mi:longint;
begin
po:=n+;
mi:=maxlongint;
while po<> do
begin
if sid[pre[po]].cap<mi then mi:=sid[pre[po]].cap;
po:=sid[pre[po]].u;
end; po:=n+;
while po<> do
begin
inc(ans,mi*sid[pre[po]].cost);
dec(sid[pre[po]].cap,mi);
inc(sid[pre[po] xor ].cap,mi);
po:=sid[pre[po]].u;
end;
end;

-----------------------------------------------------------------------------------------

BZOJ4276

用线段树优化费用流

#include <cstdio>
#include <iostream>
using namespace std; struct edge{
int fr,des,cap,cos,next;
}sid[]; struct treenode{
int l,r,lc,rc;
}tr[]; int cnt,nd[],dl[],head,tail,sor,tar,dis[],b[],path[],ans,scnt; void addedge(int fr,int to,int cap,int cos){
sid[scnt].fr=fr;sid[scnt].des=to;sid[scnt].cap=cap;sid[scnt].cos=cos;sid[scnt].next=nd[fr];nd[fr]=scnt++;
sid[scnt].fr=to;sid[scnt].des=fr;sid[scnt].cap=;sid[scnt].cos=-cos;sid[scnt].next=nd[to];nd[to]=scnt++;
} int spfa(){
dl[head=tail=]=sor;
for (int i=;i<=tar;i++) dis[i]=,b[i]=;
b[sor]=;
dis[sor]=;
while (head<=tail){
for (int p=nd[dl[head]];p!=-;p=sid[p].next)
if ((sid[p].cap!=)&&(dis[sid[p].des]<dis[dl[head]]+sid[p].cos)){
path[sid[p].des]=p;
if (b[sid[p].des]==){
dl[++tail]=sid[p].des;
b[sid[p].des]=;
}
dis[sid[p].des]=dis[dl[head]]+sid[p].cos;
}
b[dl[head++]]=;
} if (dis[tar]==) return();else return();
} void aug(){
int po=tar,flow=1e9; while (po!=sor){
int p=path[po];
flow=min(flow,sid[p].cap);
po=sid[p].fr;
} po=tar; while (po!=sor){
int p=path[po];
sid[p].cap-=flow;
ans+=flow*sid[p].cos;
sid[p^].cap+=flow;
po=sid[p].fr;
}
} void build(int l,int r){
tr[++cnt].l=l;tr[cnt].r=r;
if (l==r) {addedge(cnt,tar,,);return;} int t=cnt,mid=(l+r)>>;
tr[t].lc=cnt+;addedge(t,cnt+,1e9,);
build(l,mid);
tr[t].rc=cnt+;addedge(t,cnt+,1e9,);
build(mid+,r);
} void query(int po,int l,int r,int fr){
if (tr[po].l==l&&tr[po].r==r){
addedge(fr,po,1e9,);return;
} int mid=(tr[po].l+tr[po].r)>>;
if (l<=mid) query(tr[po].lc,l,min(mid,r),fr);
if (r>mid) query(tr[po].rc,max(mid+,l),r,fr);
} int main(){
int n,t1,t2,t3;
scanf("%d",&n);
sor=;tar=;
for (int i=sor;i<=tar;i++) nd[i]=-;
build(,); for (int i=;i<=n;i++){
scanf("%d%d%d",&t1,&t2,&t3);t2--;
addedge(sor,++cnt,,t3);
query(,t1,t2,cnt);
} while (spfa())
aug(); printf("%d\n",ans);
}

最小/大费用最大流模板(codevs1914)的更多相关文章

  1. 洛谷P4014 分配问题【最小/大费用流】题解+AC代码

    洛谷P4014 分配问题[最小/大费用流]题解+AC代码 题目描述 有 n 件工作要分配给 n 个人做.第 i 个人做第 j 件工作产生的效益为c ij. 试设计一个将 n 件工作分配给 n 个人做的 ...

  2. 图论算法-最小费用最大流模板【EK;Dinic】

    图论算法-最小费用最大流模板[EK;Dinic] EK模板 const int inf=1000000000; int n,m,s,t; struct node{int v,w,c;}; vector ...

  3. HDU3376 最小费用最大流 模板2

    Matrix Again Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 102400/102400 K (Java/Others)To ...

  4. 洛谷P3381 最小费用最大流模板

    https://www.luogu.org/problem/P3381 题目描述 如题,给出一个网络图,以及其源点和汇点,每条边已知其最大流量和单位流量费用,求出其网络最大流和在最大流情况下的最小费用 ...

  5. 最大流 && 最小费用最大流模板

    模板从  这里   搬运,链接博客还有很多网络流题集题解参考. 最大流模板 ( 可处理重边 ) ; const int INF = 0x3f3f3f3f; struct Edge { int from ...

  6. poj 2195 最小费用最大流模板

    /*Source Code Problem: 2195 User: HEU_daoguang Memory: 1172K Time: 94MS Language: G++ Result: Accept ...

  7. Doctor NiGONiGO’s multi-core CPU(最小费用最大流模板)

    题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=693 题意:有一个 k 核的处理器和 n 个工作,全部的工作都须要在一个核上处理一个单位的 ...

  8. 【网络流#2】hdu 1533 - 最小费用最大流模板题

    最小费用最大流,即MCMF(Minimum Cost Maximum Flow)问题 嗯~第一次写费用流题... 这道就是费用流的模板题,找不到更裸的题了 建图:每个m(Man)作为源点,每个H(Ho ...

  9. 最小费用最大流模板 poj 2159 模板水题

    Going Home Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 15944   Accepted: 8167 Descr ...

随机推荐

  1. iOS MJRefresh下拉刷新(上拉加载)使用详解

    下拉刷新控件目前比较火的有好几种,本人用过MJRefresh 和 SVPullToRefresh,相对而言,前者比后者可定制化.拓展新都更高一点. 因此本文着重讲一下MJRefresh的简单用法. 导 ...

  2. C++杂谈(三)产生随机数与time函数

    产生随机数在程序中很有用,这篇文章简单介绍一下产生随机数的方法. 伪随机数 使用标准库<cstdlib>中的rand()函数产生随机数. #include<iostream> ...

  3. (安装linux操作系统)

    安装linux centos系统. 准备一张centos的镜像可以去官网下载. 准备VMware Workstation官网下载. 作为初学者一般都用虚拟机安装(VMwareWorkstation), ...

  4. linux 目录结构及其相关命令

    目录也是一个文件,它的唯一功能是用来保存文件及其相关信息.所有的文件,包括普通文件.设备文件和目录文件,都会被保存到目录中. 主目录 登录后,你所在的位置就是你的主目录(或登录目录),如果是root用 ...

  5. 在Python命令行和VIM中自动补全

    作者:gnuhpc 出处:http://www.cnblogs.com/gnuhpc/ 1. VIM下的配置: wget https://github.com/rkulla/pydiction/arc ...

  6. z-index学习知识小结

    一.z-index七阶层叠顺序表 1.层叠顺序的大小比较: background/border < 负z-index < block块状水平盒子 < float浮动盒子 < i ...

  7. Random number

    Original #include <stdlib.h> #include <time.h> srand(time(NULL)); rand(); The versions o ...

  8. POJ1651Multiplication Puzzle[区间DP]

    Multiplication Puzzle Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8737   Accepted:  ...

  9. SQL存储过程的调用及写法

    调用函数: public class SqlProcess { ; public DataSet ReturnSet = null; public SqlDataAdapter adapter = n ...

  10. [No000016]为什么假期计划总是做不到?