最小费用流模板

和最大流模板对比着看:最大流模板(Dinic)

贴上最小费用流模板:

const   int oo=1e9;
const   int mm=11111111;
const   int mn=888888;
int node,src,dest,edge;
int ver[mm],flow[mm],cost[mm],nex[mm];
int head[mn],dis[mn],p[mn],q[mn],vis[mn];
/**这些变量基本与最大流相同,增加了
 cost 表示边的费用,
 p 记录可行流上节点对应的反向边
 */
void prepare(int _node,int _src,int _dest)
{
    node=_node,src=_src,dest=_dest;
    for(int i=0; i<node; i++)head[i]=-1,vis[i]=0;
    edge=0;
}
void addedge(int u,int v,int f,int c)
{
    ver[edge]=v,flow[edge]=f,cost[edge]=c,nex[edge]=head[u],head[u]=edge++;
    ver[edge]=u,flow[edge]=0,cost[edge]=-c,nex[edge]=head[v],head[v]=edge++;
}
/**以上同最大流*/
/**spfa 求最短路,并用 p 记录最短路上的边*/
bool spfa()
{
    int i,u,v,l,r=0,tmp;
    for(i=0; i<node; ++i)dis[i]=oo;
    dis[q[r++]=src]=0;
    p[src]=p[dest]=-1;
    for(l=0; l!=r; (++l>=mn)?l=0:l)
        for(i=head[u=q[l]],vis[u]=0; i>=0; i=nex[i])
            if(flow[i]&&dis[v=ver[i]]>(tmp=dis[u]+cost[i]))
            {
                dis[v]=tmp;
                p[v]=i^1;
                if(vis[v]) continue;
                vis[q[r++]=v]=1;
                if(r>=mn)r=0;
            }
    return p[dest]>-1;
}
/**源点到汇点的一条最短路即可行流,不断的找这样的可行流*/
int SpfaFlow()
{
    int i,ret=0,delta;
    while(spfa())
    {
        for(i=p[dest],delta=oo; i>=0; i=p[ver[i]])
            if(flow[i^1]<delta)delta=flow[i^1];
        for(i=p[dest]; i>=0; i=p[ver[i]])
            flow[i]+=delta,flow[i^1]-=delta;
        ret+=delta*dis[dest];
    }
    return ret;
}
时间: 2024-11-26 05:41:01

最小费用流模板的相关文章

HYSBZ 1061 志愿者招募 【最小费用流】【差分】【最小费用流模板】

#include<stdio.h> #include<queue> #define MAXN 1003 #define MAXM 10002*4 #define INF 10000000 using namespace std; //起点编号必须最小,终点编号必须最大 bool vis[MAXN]; //spfa中记录是否在队列里边 struct edge{ edge *next,*op; //op是指向反向边 int t,c,v; //t下一个点编号,c容量,v权值 }ES[MA

最大流 最小费用流模板

1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <queue> 5 using namespace std; 6 const int INF = 0x3f3f3f3f; 7 const int N = 10005; 8 const int M = 100005; 9 struct type{ 10 int u, v, w, next; 11 }edge[M

HDU-1533 Going Home(二分图匹配)

最近开始做最小费用流的题目,该题是二分图完美匹配下的最小权匹配,所谓完美匹配就是说从源点流入的总流量等于从汇点流出的总流量,在这种状态下的最小费用 . 那么显然是要套用最小费用流模板,另外二分图匹配的第一步就是要划分集合,划分两个集合,集合A与源点相连,集合B与汇点相连,至于容量和权值就要依据题目而定 . 比如该题,因为每个小人恰好能对应一个房子,所以每个小人与汇点的容量为1,房子与汇点的容量为1,这样就保证了是完美匹配. 那么下一步要建立两个集合中元素之间的关系,那么容量显然是可以随便赋值的,

poj 2135 Farm Tour 最小费用流入门模板

题意: 求点1到点n再从点n回点1不经过同一条路的最短路. 分析: 建图容易,给一组针对求两次最短路的数据: 4 5 1 2 1 1 3 100 2 4 100 2 3 1 3 4 1 接下来上最小费用流的模板就好. 代码: //poj 2135 //sep9 #include <iostream> #include <queue> using namespace std; const int maxN=2048; const int maxM=20024; struct Edge

最小费用流spfa算法模板(pascal)

以前写过,现在的码风与以前有些变化,主要是用数组模拟邻接表存图,以前是用指针存图. 以前的博文:http://www.cnblogs.com/Currier/p/6387732.html 洛谷可评测. 传送门:https://www.luogu.org/problem/show?pid=3381 1 program rrr(input,output); 2 const 3 inf=123456789; 4 type 5 etype=record 6 t,c,w,next,rev:longint;

Going Home (hdu 1533 最小费用流)

集训的图论都快结束了,我才看懂了最小费用流,惭愧啊. = = 但是今天机械键盘到了,有弄好了自行车,好高兴\(^o^)/~ 其实也不是看懂,就会套个模板而已.... 这题最重要的就是一个: 多组输入一定要写个init()函数清空,并且输入的时候每次都要调用init() #include <map> #include <set> #include <list> #include <cmath> #include <queue> #include &

HDU 1533--Going Home【最小费用最大流 &amp;&amp; 模板】

Going Home Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 3452    Accepted Submission(s): 1771 Problem Description On a grid map there are n little men and n houses. In each unit time, every

POJ 2516 最小费用流

依然最小费用最大流模板题 建边麻烦了些 #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <cmath> #include <vector> #include <utility> #include <stack> #include <queue> #include <ma

[haoi2010]订货 最小费用流

这道题oj上的标签是动态规划,但我想不出来动态规划怎么搞,空间不爆,时间也要爆的: 好的,不扯淡,此题正常做法是最小费用流: 这道题我写了两遍,为什么呢?原因是第一次写的时候,不会写费用流,又恰好没带书,所以搁置了: 第二次又写到这道题了,有点生气,一鼓作气学了费用流,紧跟着敲了这道题: 也算一道费用流模板吧: 1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cstrin