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


题目描述

有 n 件工作要分配给 n 个人做。第 i 个人做第 j 件工作产生的效益为c ij。 试设计一个将 n 件工作分配给 n 个人做的分配方案,使产生的总效益最大。

输入格式:

文件的第 1 行有 1 个正整数 n,表示有 n 件工作要分配给 n 个人做。接下来的 n 行中,每行有 n 个整数c ij,表示第 i 个人做第 j 件工作产生的效益为c ij 。

输出格式:

两行分别输出最小总效益和最大总效益。

输入样例

5

2 2 2 1 2

2 3 1 2 4

2 0 1 1 1

2 3 4 3 3

3 2 1 2 1

输出样例

5

14

说明

1001≤n≤100


题目分析

首先将讲讲最小收益

超级源点向每个工人连边

容量为1,费用为0

表示限制每个工人只能有一个工作

每个工人向每个工作连边

容量为1,费用为既定收益

这样当这条边有流时

费用即为收益

每个工作向超级汇点连边

容量为1,费用为0

表示限制每个工作只能被做一次

然后跑费用流就可以了

最大收益,即最大费用流

将原图中的边的费用全部取反

然后跑费用流

最后费用取反即可

这里由于要跑两次费用流

蒟蒻的我只想到了把原来存边的数组开了二维

即E[0][]表示最小费用用的图,E[1][]表示最大费用用的图

不知道有没有更好的办法

有没有哪位daolao教教我QAQ


#include<iostream>
#include<cstdio>
#include<vector>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;

const int inf=2139062143;
int m,n;
int s=0,t;
struct node{int v,f,c,nxt;}E[2][1000010];
int head[2][1000010];//这里是蒟蒻开二维存图的方式
int d[2][1000010];
bool vis[1000010];
int ans,tot=1;

int read()
{
    int f=1,x=0;
    char ss=getchar();
    while(ss<'0'||ss>'9'){if(ss=='-')f=-1;ss=getchar();}
    while(ss>='0'&&ss<='9'){x=x*10+ss-'0';ss=getchar();}
    return f*x;
}

void add(int u,int v,int f,int c,int p)
{
    E[p][++tot].nxt=head[p][u];
    E[p][tot].v=v;
    E[p][tot].f=f;
    E[p][tot].c=c;
    head[p][u]=tot;
}

bool bfs(int p)
{
    memset(d,127,sizeof(d)); d[p][s]=0;
    queue<int> q; q.push(s); vis[s]=true;

    while(!q.empty())
    {
        int u=q.front();
        q.pop(); vis[u]=false;
        for(int i=head[p][u];i;i=E[p][i].nxt)
        {
            int v=E[p][i].v;
            if(E[p][i].f&&d[p][v]>d[p][u]+E[p][i].c)
            {
                d[p][v]=d[p][u]+E[p][i].c;
                if(!vis[v])
                {
                    q.push(v);
                    vis[v]=true;
                }
            }
        }
    }
    return d[p][t]!=inf;
}

int dfs(int u,int cap,int p)
{
    if(u==t)
    return cap;

    int flow=cap;
    vis[u]=true;

    for(int i=head[p][u];i;i=E[p][i].nxt)
    {
        int v=E[p][i].v;
        if(d[p][v]==d[p][u]+E[p][i].c&&E[p][i].f&&flow&&!vis[v])
        {
            int f=dfs(v,min(E[p][i].f,flow),p);
            flow-=f;
            E[p][i].f-=f;
            E[p][i^1].f+=f;
            ans+=E[p][i].c*f;
        }
    }
    vis[u]=false;
    return cap-flow;
}

int main()
{
    n=read();
    t=n*2+1;
    for(int i=1;i<=n;i++)
    {
        add(s,i,1,0,0);add(i,s,0,0,0);
        add(s,i,1,0,1);add(i,s,0,0,1);
        //超源向工人连边

        add(i+n,t,1,0,0);add(t,i+n,0,0,0);
        add(i+n,t,1,0,1);add(t,i+n,0,0,1);
        //工作向超汇连边
    }

    for(int i=1;i<=n;i++)
    {
        for(int j=n+1;j<=n*2;j++)
        {
            int c=read();
            add(i,j,1,c,0);add(j,i,0,-c,0);
            add(i,j,1,-c,1);add(j,i,0,c,1);
            //工人向工作连边
        }
    }

    while(bfs(0))//最小费用流
    dfs(s,inf,0);
    cout<<ans<<endl;

    ans=0;
    while(bfs(1))//最大费用流
    dfs(s,inf,1);
    cout<<-ans<<endl;

    return 0;
}

洛谷P4014 分配问题【最小/大费用流】题解+AC代码的更多相关文章

  1. 洛谷 P4014 分配问题 【最小费用最大流+最大费用最大流】

    其实KM更快--但是这道题不卡,所以用了简单粗暴的费用流,建图非常简单,s向所有人连流量为1费用为0的边来限制流量,所有工作向t连流量为1费用为0的边,然后对应的人和工作连(i,j,1,cij),跑一 ...

  2. 洛谷P4014 分配问题(费用流)

    传送门 可以把原图看做一个二分图,人在左边,任务在右边,求一个带权的最大和最小完美匹配 然而我并不会二分图做法,所以只好直接用费用流套进去,求一个最小费用最大流和最大费用最大流即可 //minamot ...

  3. 洛谷P4014 分配问题(费用流)

    题目描述 有 nn 件工作要分配给 nn 个人做.第 ii 个人做第 jj 件工作产生的效益为 c_{ij}cij​ .试设计一个将 nn 件工作分配给 nn 个人做的分配方案,使产生的总效益最大. ...

  4. 洛谷——P4014 分配问题

    P4014 分配问题 题目描述 有 nn 件工作要分配给 nn 个人做.第 ii 个人做第 jj 件工作产生的效益为 c_{ij}cij​ .试设计一个将 nn 件工作分配给 nn 个人做的分配方案, ...

  5. 洛谷P2517 HAOI2010 订货 (费用流)

    标准的费用流问题,关键在于巧妙地建模 一共有n个月份,源点设为0,汇点设为n+1 1.源点向所有月份连边,容量为正无穷,费用为该月进货的费用 2.每个月向下一个月连边,容量为仓库容量,费用为存货费用 ...

  6. 洛谷 1004 dp或最大费用流

    思路: dp方法: 设dp[i][j][k][l]为两条没有交叉的路径分别走到(i,j)和(k,l)处最大价值. 则转移方程为 dp[i][j][k][l]=max(dp[i-1][j][k-1][l ...

  7. 洛谷P4003 无限之环(费用流)

    传送门 神仙题啊……不看题解我可能一年都不一定做得出来……FlashHu大佬太强啦 到底是得有怎样的脑回路才能一眼看去就是费用流啊…… 建好图之后套个板子就好了,那么我们着重来讨论一下怎么建图 首先, ...

  8. 洛谷P4012 深海机器人问题(费用流)

    题目描述 深海资源考察探险队的潜艇将到达深海的海底进行科学考察. 潜艇内有多个深海机器人.潜艇到达深海海底后,深海机器人将离开潜艇向预定目标移动. 深海机器人在移动中还必须沿途采集海底生物标本.沿途生 ...

  9. 洛谷P4014分配问题——网络流24题

    题目:https://www.luogu.org/problemnew/show/P4014 最大/小费用最大流裸题. 代码如下: #include<iostream> #include& ...

随机推荐

  1. beetl 配置多视图解析器

    如下配置,指定了三个视图解析器,一个用于beetl页面渲染,一个用于cms,采用了beetl技术,另外一个一些遗留的页面采用jsp <bean name="beetlConfig&qu ...

  2. Freemarker 入门示例

    初步学习freemarker ,先做一个简单的HelloWord程序! 新建一个WEB工程,下载(我使用的是freemarker-2.3.20)freemarker并导入freemarker.jar, ...

  3. 使用VSCode 编译调试QT程序

    预备知识 bat文件,或者其他的脚本语法. qmake基本语法,qmake shadow build是啥. vscode 的task,lanch的配置. 前提 各个程序正确安装,即使用QtCreato ...

  4. elasticsearch安装ik分词器

    一.概要: 1.es默认的分词器对中文支持不好,会分割成一个个的汉字.ik分词器对中文的支持要好一些,主要由两种模式:ik_smart和ik_max_word 2.环境 操作系统:centos es版 ...

  5. CSS3 动画及过渡详解

    今天开始我们一起来学习有关于CSS3制作动画的几个属性:变形(transform).过渡(transition)和动画(animation)等CSS3技术. 首先我们先来了解一下变形(transfor ...

  6. JAVA学习,是一条漫长的道路

    我在Java 1.0正式问世前就开始学习Java,这么多年过去了,到现在我的Java学习历程还没有停过.我阅读原文书,研究原始码,撰写程序,自认为走得扎实,不奢望一步登天.像我这样老式的学习方式,显然 ...

  7. 面试必问的 volatile,你了解多少?

    前言 Java中volatile这个热门的关键字,在面试中经常会被提及,在各种技术交流群中也经常被讨论,但似乎讨论不出一个完美的结果,带着种种疑惑,准备从JVM.C++.汇编的角度重新梳理一遍. vo ...

  8. 网站静态化处理—web前端优化—上(11)

    网站静态化处理这个系列马上就要结束了,今天我要讲讲本系列最后一个重要的主题web前端优化.在开始谈论本主题之前,我想问大家一个问题,网站静态化处理技术到底是应该归属于web服务端的技术范畴还是应该归属 ...

  9. js中常用的方法(数组篇)

    1.replace(),根据释义,即为代替,用法为: stringObject.replace(regexp/substr,replacement)括号内前者是待匹配字符串,并用后者代替这个字符串.例 ...

  10. Java细节

    native关键字用法 native是与C++联合开发的时候用的!java自己开发不用的! 使用native关键字说明这个方法是原生函数,也就是这个方法是用C/C++语言实现的,并且被编译成了DLL, ...