最小费用最大流 模板

nm无影响   s为源点  t为汇点

最大流为maxflow  最小费用为 mincost

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn=100010;

bool vis[maxn];
int n,m,s,t,x,y,z,f,dis[maxn],pre[maxn],last[maxn],flow[maxn],maxflow,mincost;
//dis最小花费;pre每个点的前驱;last每个点的所连的前一条边;flow源点到此处的流量
struct Edge{
    int to,next,flow,dis;//flow流量 dis花费
}edge[maxn];
int head[maxn],num_edge;
queue <int> q;

void add_edge(int from,int to,int flow,int dis)
{
    edge[++num_edge].next=head[from];
    edge[num_edge].to=to;
    edge[num_edge].flow=flow;
    edge[num_edge].dis=dis;
    head[from]=num_edge;

    edge[++num_edge].next=head[to];
    edge[num_edge].to=from;
    edge[num_edge].flow=0;
    edge[num_edge].dis=-dis;
    head[to]=num_edge;

}

bool spfa(int s,int t)
{
    memset(dis,0x7f,sizeof(dis));
    memset(flow,0x7f,sizeof(flow));
    memset(vis,0,sizeof(vis));
    q.push(s); vis[s]=1; dis[s]=0; pre[t]=-1;

    while (!q.empty())
    {
        int now=q.front();
        q.pop();
        vis[now]=0;
        for (int i=head[now]; i!=-1; i=edge[i].next)
        {
            if (edge[i].flow>0 && dis[edge[i].to]>dis[now]+edge[i].dis)//正边
            {
                dis[edge[i].to]=dis[now]+edge[i].dis;
                pre[edge[i].to]=now;
                last[edge[i].to]=i;
                flow[edge[i].to]=min(flow[now],edge[i].flow);//
                if (!vis[edge[i].to])
                {
                    vis[edge[i].to]=1;
                    q.push(edge[i].to);
                }
            }
        }
    }
    return pre[t]!=-1;
}

void MCMF()
{
    while (spfa(s,t))
    {
        int now=t;
        maxflow+=flow[t];
        mincost+=flow[t]*dis[t];
        while (now!=s)
        {//从源点一直回溯到汇点
            edge[last[now]].flow-=flow[t];//flow和dis容易搞混
            edge[last[now]^1].flow+=flow[t];
            now=pre[now];
        }
    }
}

int main()
{
    memset(head,-1,sizeof(head)); num_edge=-1;//初始化
    scanf("%d%d%d%d",&n,&m,&s,&t);
    for (int i=1; i<=m; i++)
    {
        scanf("%d%d%d%d",&x,&y,&z,&f);
        add_edge(x,y,z,f); //add_edge(y,x,0,-f);
        //反边的流量为0,花费是相反数
    }
    MCMF();
    printf("%d %d",maxflow,mincost);
    return 0;
}

原文地址:https://www.cnblogs.com/bxd123/p/10927111.html

时间: 2024-10-13 23:40:08

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

POJ2135Farm Tour(最小费用最大流模板)

题目链接:http://poj.org/problem?id=2135 题意:农场主想从1到n,然后从n到1,每条边最多走一次,不能走重复的路,问最短距离是多少. 建图:取超级源点s,并与房子连一条边,容量为2,费用为0:取barn与超级汇点 t 的边的容量为2,费用为0 房子与barn的费用为距离,容量为1 #include <iostream> #include <cstdlib> #include <cstdio> #include <cstring>

POJ2135 最小费用最大流模板题

练练最小费用最大流 此外此题也是一经典图论题 题意:找出两条从s到t的不同的路径,距离最短. 要注意:这里是无向边,要变成两条有向边 #include <cstdio> #include <cstring> #define MAXN 1005 #define MAXM 10005 #define INF 0x3f3f3f3f struct Edge { int y,c,w,ne;//c容量 w费用 }e[MAXM*4]; int n,m,x,y,w; int s,t,Maxflow

poj 2135 Farm Tour (最小费用最大流模板)

网络流的费用: 在实际应用中,与网络流有关的问题,不仅涉及流量,而且还有费用的因素.网络的每一条边(v,w)除了给定容量cap(v,w)外,还定义了一个单位流量费用cost(v,w) 最小费用最大流问题 给定网络G,要求G的一个最大用流flow,使流的总费用最小. 求解MCMF问题的算法: 最小费用最大流最常用和基本的算法我们可以称它为最小费用路算法,其思想与求最大流的增广路算法类似,不断在残流网络中寻找从源s到汇t的最小费用路,即残流网络中从s到t的以费用为权的最短路,然后沿最小费用路增流,直

poj 2195 最小费用最大流模板

/*Source Code Problem: 2195 User: HEU_daoguang Memory: 1172K Time: 94MS Language: G++ Result: Accepted Source Code */ #include <iostream> #include <stdio.h> #include <queue> #include <math.h> #include <string.h> using namespa

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

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

题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=693 题意:有一个 k 核的处理器和 n 个工作,全部的工作都须要在一个核上处理一个单位的时间,每一个核在不同一时候间处理同一个工作的花费是递增的,每一个核一次仅仅能处理一个工作,求运用k个核处理这n个工作的最小花费. 分析: 分析可知,求处理全部工作的最小花费,而每次选择怎么处理我们能够通过容量都为1的边来让网络流处理,这样就转化为最小费用最大流. 首先设一个超级源点s,连接全部的工作

Farm Tour(最小费用最大流模板)

Farm Tour Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 18150   Accepted: 7023 Description When FJ's friends visit him on the farm, he likes to show them around. His farm comprises N (1 <= N <= 1000) fields numbered 1..N, the first of

POJ-2195 Going Home(最小费用最大流模板)

题目链接:POJ-2195 Going Home 题意 给出$N$行$M$列的网格,'m'表示人,'H'表示房子,且'm'和'H'的数量相同,一个人只能进一间房子,一间房子也只能给一个人进去,人可走上下左右四个方向,现在要让所有人进入房子,求最短路径和. 思路 这是一个二分图带权最小匹配问题,可直接用最小费用最大流求解. 源点向人各连一条容量为1,费用为0的边,每个人向每间房子连容量为1,费用为距离的边,每间房子向汇点连容量为1,费用为0的边,然后跑最小费用最大流即可. 代码实现 #includ

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

嗯~第一次写费用流题... 这道就是费用流的模板题,找不到更裸的题了 建图:每个m(Man)作为源点,每个H(House)作为汇点,各个源点与汇点分别连一条边,这条边的流量是1(因为每个源点只能走一条边到汇点),费用是 从源点走到汇点的步数,因为有多个源点与汇点,要建一个超级源点与超级汇点,超级源点与各个源点连一条流量为1,费用为0(要避免产生多余的费用)的边 按照这个图跑一发费用流即可 把代码挂上去,用的是前向星写的 1 #include<cstdio> 2 #include<cstr