HDU 4494 Teamwork(最大流-Dinic+最小费用最大流-mcmf)

网络流模板 —— Dinic算法(弧优化),最小费用最大流 学了几天感觉对网络流算是入门了,稍稍整理一下,同时在学习网络流的过程中看到了三篇别人很不错的blog(如下) 感谢 ~~ 网络流相关定义及原理:https://www.cnblogs.com/rmy020718/p/9546071.html Dinic算法+弧优化:https://www.cnblogs.com/SYCstudio/p/7260613.html 网络流常见建模方法:https://... 阅读详情

Description

m种工人,n−1个工作,给出第i个工作地点的坐标,开始时间,工作完成所需时间以及所需每种工人的数量,两个工作地点之间的距离定义为欧氏距离,工人速度为单位距离每单位时间,工人完成一个工作后如果在到达另一个工作地点时还没到开始时间即可继续工作,问至少要多少名工人才能完成这n项工作

Input

第一行一整数T表示用例组数,每组用例输入两整数n和m分别表示工作数量和工人数量,之后输入工人初始坐标,最后n−1行每行输入该工作的坐标,开始时间,工作完成所需时间以及所需每种工人的数量(T≤25,n≤150,m≤5)

Output

对于每组用例,输出完成所有工作至少需要的工人数量

Sample Input

2
4 1
0 0
0 1 1 1 3
1 1 3 3 4
1 0 10 1 5
4 1
0 0
0 1 1 1 3
1 1 3 3 4
1 0 3 1 5

Sample Output

5
9

Solution1

可以看出每种工人之间相互独立,所以可以单独分析,考虑完成所有工作所需第k种工人的数量,考虑把工人看作费用,把一项工作所需工人看作流量,那么问题转化为一个费用流,由于工人可以做多项工作,把每个工作拆点i,i+n−1,建图如下:

1.源点向i连容量为无穷,费用为1的边,体现出每个工人是一个费用

2.i向汇点连容量为num[i][k](第i项工作所需第k种工人的数量),费用为0的边,体现出完成每项工作对工人数量的要求

3.源点向i+n−1连容量为num[i][k],费用为0的边,表示完成该项工作的工人还可以继续完成其他工作

4.i+n−1向j连容量为num[i][k],费用为0的边,如果i工作的结束时间加上i与j的距离还要早于j工作的开始时间,说明完成i工作的工人可以继续完成j工作

跑一边费用流,最小费用即为所需第k种工人的最少数量,累加起来即为答案

Code1

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<ctime>
using namespace std;
#define maxn 333
#define maxm 66666
#define INF 0x3f3f3f3f
int head[maxn],d[maxn],s,e,no,vis[maxn],pre[maxn];//s为源点,e为汇点 
struct point
{
    int u,v,flow,next,cost;
    point(){};
    point(int _u,int _v,int _next,int _flow,int _cost)
    {
        u=_u,v=_v,next=_next,flow=_flow,cost=_cost;
    } 
}p[maxm];
void add(int x,int y,int z,int c)//从x到y建一条容量为z,花费为c的边 
{
    p[no]=point(x,y,head[x],z,c);   
    head[x]=no++;
    p[no]=point(y,x,head[y],0,-c);  
    head[y]=no++;
}
void init()//初始化 
{
    memset(head,-1,sizeof(head));
    no=0;
}
bool spfa()
{
    int i,x,y;
    queue<int>q;
    memset(d,0x3f,sizeof(d));
    memset(vis,false,sizeof(vis));
    memset(pre,-1,sizeof(pre));
    d[s]=0;   
    vis[s]=true;  
    q.push(s);
    while(!q.empty())
    {
        x=q.front();  
        q.pop();    
        vis[x]=false;
        for(i=head[x];i!=-1;i=p[i].next)
        {
            if(p[i].flow&&d[y=p[i].v]>d[x]+p[i].cost)
            {
                d[y]=d[x]+p[i].cost;   
                pre[y]=i;
                if(vis[y])  
                    continue;
                vis[y]=true;  
                q.push(y);
            }  
        }  
    }
    return d[e]!=d[e+1];
}
int mcmf()//最小费用最大流 
{
    int mincost=0,maxflow=0,minflow,i;
    while(spfa())
    {
        //if(d[e]>=0)break;//可行流 
        minflow=INF;
        for(i=pre[e];i!=-1;i=pre[p[i].u])
            minflow=min(minflow,p[i].flow);
        for(i=pre[e];i!=-1;i=pre[p[i].u])
        {
            p[i].flow-=minflow;
            p[i^1].flow+=minflow;
        }
        mincost+=d[e]*minflow; 
        maxflow+=minflow;
    }
    return mincost;//最小费用,最大流为maxflow 
}
struct node
{
    double x,y,b,p;
    int num[6];
}a[maxn],o;
double dis(node a,node b)
{
    double x=a.x-b.x,y=a.y-b.y;
    return sqrt(x*x+y*y);
}
int T,n,m;
int main()
{
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m);
        scanf("%lf%lf",&o.x,&o.y);
        for(int i=1;i<n;i++)
        {
            scanf("%lf%lf%lf%lf",&a[i].x,&a[i].y,&a[i].b,&a[i].p);
            for(int j=1;j<=m;j++)scanf("%d",&a[i].num[j]);
        }
        s=0,e=2*n-1;
        int ans=0;
        for(int k=1;k<=m;k++)
        {
            init();
            for(int i=1;i<n;i++)
            {
                add(s,i,INF,1);
                add(i,e,a[i].num[k],0);
                add(s,i+n-1,a[i].num[k],0);
                for(int j=1;j<n;j++)
                    if(i!=j&&a[i].b+a[i].p+dis(a[i],a[j])<=a[j].b)
                        add(i+n-1,j,a[i].num[k],0);
            }
            ans+=mcmf();
        }
        printf("%d\n",ans);
    }
    return 0;
}

Solution2

同样考虑完成所有工作所需第k种工人的数量,如果去掉工人可以完成多项工作的条件,那么所需人数应为ans=∑i=1n−1num[i][k],当工人可以完成多项工作时,我们考虑求出完成某些工作的工人中有多少还可以做其他工作,拿ans减掉这些重复工作的工人数量即为所需的最少人数,依旧把第i个工作拆点为i,i+n−1,建图如下:

1.源点向i建容量为num[i][k]的边,表示完成第i项工作的工人人数

2.i+n−1向汇点连容量为num[i][k]的边,表示完成该项工作的工人中之前做过工作的至多为num[i][k]

3.i向j+n−1连容量为num[i][k],费用为0的边,如果i工作的结束时间加上i与j的距离还要早于j工作的开始时间,说明完成i工作的工人可以继续完成j工作

ans减去最大流即为完成所有工作所需第k种工人的数量,累加即为答案

Code2

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<ctime>
using namespace std;
#define maxn 333
#define maxm 66666
#define INF 0x3f3f3f3f
int head[maxn],cur[maxn],d[maxn],st[maxm],s,e,no;//s为源点,e为汇点,n为点数,no为边数 
struct point
{
    int u,v,flow,next;
    point(){};
    point(int x,int y,int z,int w):u(x),v(y),next(z),flow(w){};
}p[maxm];
void add(int x,int y,int z)//从x到y建容量为z的边 
{
    p[no]=point(x,y,head[x],z);//前向弧,标号为偶 
    head[x]=no++;
    p[no]=point(y,x,head[y],0);//后向弧,标号为奇 
    head[y]=no++;
}
void init()//初始化 
{
    memset(head,-1,sizeof(head));
    no=0;
}
bool bfs()
{
    int i,x,y;
    queue<int>q;
    memset(d,-1,sizeof(d));
    d[s]=0; 
    q.push(s);
    while(!q.empty())
    {
        x=q.front();    
        q.pop();
        for(i=head[x];i!=-1;i=p[i].next)
        {
            if(p[i].flow&& d[y=p[i].v]<0)
            {
                d[y]=d[x]+1;
                if(y==e)    
                    return true;
                q.push(y);
            }
        }
    }
    return false;
}
int dinic()//最大流 
{
    int i,loc,top,x=s,nowflow,maxflow=0;
    while(bfs())
    {
        memcpy(cur,head,sizeof(head));
        top=0;
        while(true)
        {
            if(x==e)
            {
                nowflow=INF;
                for(i=0;i<top;i++)
                {
                    if(nowflow>p[st[i]].flow)
                    {
                        nowflow=p[st[i]].flow;
                        loc=i;
                    }
                }
                for(i=0;i<top;i++)
                {
                    p[st[i]].flow-=nowflow;
                    p[st[i]^1].flow+=nowflow;
                }
                maxflow+=nowflow;
                top=loc;    
                x=p[st[top]].u;
            }
            for(i=cur[x];i!=-1;i=p[i].next)
                if(p[i].flow&&d[p[i].v]==d[x]+1) 
                    break;
            cur[x]=i;
            if(i!=-1)
            {
                st[top++]=i;
                x=p[i].v;
            }
            else 
            {
                if(!top)    
                    break;
                d[x]=-1;
                x=p[st[--top]].u;
            }
        }
    }
    return maxflow;
}
struct node
{
    double x,y,b,p;
    int num[6];
}a[maxn],o;
double dis(node a,node b)
{
    double x=a.x-b.x,y=a.y-b.y;
    return sqrt(x*x+y*y);
}
int T,n,m;
int main()
{
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m);
        scanf("%lf%lf",&o.x,&o.y);
        int ans=0;
        for(int i=1;i<n;i++)
        {
            scanf("%lf%lf%lf%lf",&a[i].x,&a[i].y,&a[i].b,&a[i].p);
            for(int j=1;j<=m;j++)scanf("%d",&a[i].num[j]),ans+=a[i].num[j];
        }
        s=0,e=2*n-1;
        for(int k=1;k<=m;k++)
        {
            init();
            for(int i=1;i<n;i++)
            {
                add(s,i,a[i].num[k]);
                add(i+n-1,e,a[i].num[k]);
                for(int j=1;j<n;j++)
                    if(i!=j&&a[i].b+a[i].p+dis(a[i],a[j])<=a[j].b)
                        add(i,j+n-1,a[i].num[k]);
            }
            ans-=dinic();
        }
        printf("%d\n",ans);
    }
    return 0;
}
一句话网络流(EK,Dinic,最小费最大流,(最大/最小)可行流,最小费用可行流) EK算法求最大流: BFS找增广路增广直到无法增广 复杂度:O(V*E^2) 核心代码(邻接表存图):(一开始学最大流的时候写的代码,非常丑) int pre[maxn]; int vis[maxn]={0}; bool bfs(){//bfs求路径 for(int i = 0;i <= n+1;++i) vis[i] = 0; queue<int> q;q.push(0);... 阅读详情

相关推荐

算法笔记:Dinic最大流和SPFA费用流

先利用BFS对残余网络分层 一个节点的深度,就是源点到它最少要经过的边数。 利用BFS对残余网络分层,分完层后,利用DFS从前一层向后一层反复寻找增广路。 这里写图片描述 分完层后,从源点开始,用DFS从前一层向后一层反复寻找增广路(即要求DFS的每一步都必须要走到下一层的节点)。 因此,前面在分层时,只要进行到汇点的层次数被算出即可停止,因为按照该DFS的规则,和汇点同层或更下一层的节点,是不可能走到汇点的。 DFS过程中,要是碰到了汇点,则说明找到了一条增广路径。此时要增加总流量的值,消减路径上各边的容

Raki_J的博客 1099

HDU 4494 Teamwork(最大流或最小费用流)

题目链接:acm.hdu.edu.cn/showproblem.php?pid=4494 题意:相当于给n个任务,给出每个任务的开始时间和持续时间,每个任务需要不同种类的人来完成,种类之间的人彼此独立不能互换,对于某个任务的人在完成任务后可以赶往其他任务帮忙,问你最少需要多少人才能完成任务 思路: 最大流:这题和最小路径覆盖思想很像,只是每个点覆盖的次数不同了,所以可以拆点构建二...

Tongqi 636

事件相机数据处理实战:从原始事件流到视觉表征的三种核心方法

本文深入探讨了事件相机数据处理的核心环节,即如何将异步、稀疏的原始事件流转换为深度学习模型可处理的视觉表征。文章重点解析了三种核心方法:逐通道累积、体素网格双线性插值和对称累积事件表示,详细阐述了其原理、代码实现、可视化效果及各自的适用场景,为事件相机在目标识别、光流估计等视觉任务中的高效应用提供了实战指南。

read5的博客 438

网络流——最小费用最大流MCMF【EK+SFPA Dinic+SPFA 模板】

什么是最小费用最大流 一个网络,每个边除了流量,还有一个单位费用,这条边的费用相当于它的单位费用乘上它的流量,我们要保持最大流的同时,还要保持边权最小,这就是最小费用最大流问题。 在一个网络流图中,最大流量只有一个,但是获得最大流的方案可能有很多种,每种不同的方案所经过的边不同因此费用也就不同,所以需要用到最短路算法。 总增广的费用=最短路费用*总流量 求MCMF中的SFPA算法就是把EK中的bfs改成spfa,这样在求最大流的过程中最小费用流也求出来了。 P3381 【模板】最小费用最大流 #incl

zjllll123的博客 781

信创改造实战:SpringBoot项目迁移到宝兰德BES 9.5.5的完整避坑指南(附依赖与web.xml配置)

本文详细介绍了将SpringBoot项目迁移到宝兰德BES 9.5.5的完整流程,包括依赖改造、web.xml配置降级等关键步骤。通过实战案例和避坑指南,帮助开发者高效完成国产中间件适配,确保项目平稳运行。特别针对Tomcat依赖排除和BES适配器选择提供了专业建议。

weixin_30689307的博客 741

北斗导航 | SPP、RTK、RTD、PPP-RTK、PPP算法原理,公式及完整matlab代码

开发参考:SPP适合入门学习GNSS定位原理和最小二乘。RTK是工程高精度定位主流方案,但依赖基站。PPP适合无基站区域的广域高精度应用。PPP-RTK是融合两者优点的新一代技术,但系统复杂度最高。· 代码资源:raPPPid(VieVS PPP)是功能完整的MATLAB开源PPP工具箱,支持多系统PPP-AR。MATLAB GPS Toolbox 提供从SPP到PPP的完整功能实现。· 实际应用:农业自动驾驶、无人机航测通常使用网络RTK;大地测量、地壳形变监测常采用PPP事后处理;

尘世冰封的专栏 829

费用流 类Dinic算法

费用流类Dinic算法 因为费用有负边权所以用spfa,求单位费用之和最小的路径 将bfs分层标记dep数组 换成 spfa分层标记dist[](最小费用和) dfs寻找多条增广路时, 开vis标记筛掉返回的边 ,且增广路顺着spfa标记的最小费用和路径走, dfs维护流和费用 Luogu P4016 注意: 环形, 最终n个仓库存货量相同, 只能在相邻的仓库之间搬运 建...

_llc的博客 1213

1个PID回路如何连接2个执行器(算法和代码)

我们先看下位置型PID的控制框图:2、PID是基于error的控制 所以反馈信号跳动、干扰非常大的话,对PID的闭环控制影响是非常大的,所以对于反馈信号、一定要抗干扰和滤波处理。3、下图是增量型PID的控制框图:4、一个PID输出回路如何连接2个执行器?(有些系统会设置热阀和冷阀才能满足控制要求)。

RXXW_Dor的博客 1811

算法学习笔记:网络流#6——dinic 求解费用流

算法学习笔记:网络流#6——dinic 求解费用流1. 前言2. 详解3. 总结 1. 前言 本篇博文将会重点讲解 dinic 求解费用流。 费用流全称:最小费用最大流,其一般的问题描述如下: 给出一张网络 G=<V,E>G=<V,E>G=<V,E>,每条边有两个权值:f,vf,vf,v。 fff 表示这条边的最大流量,vvv 表示单位花费,也就是说从这条边每流过一单位流量就要增加 vvv 的花费。 现在要求这张网络的最小费用最大流,也就是在保证总流量最大的情况下总费用最

Plozia 的小窝 2328

高效计算斐波那契数列的C++实现及源码

斐波那契数列是一个非常经典的数学问题,通常递归方式计算斐波那契数列的时候会有很大的时间复杂度问题。首先,我们需要了解斐波那契数列的定义:斐波那契数列是指前两个数都为1,从第三个开始每个数都等于它前面两个数之和。因此,斐波那契数列的前几项为:1、1、2、3、5、8、13、21……在这个代码中,我们首先判断n是否特殊情况(即n等于0、1、2),然后通过循环计算得出对应的斐波那契数列值。通过这个例子,我们可以发现使用C++语言实现高效斐波那契数列计算的代码简单、易懂,并且时间复杂度相比递归方式有了很大的提升。

TechInk的博客 547

UG\NX二次开发 获取对象的层、颜色、隐藏状态、线宽、线型、高亮显示状态

获取对象的层、颜色、隐藏状态、线宽、线型、高亮显示状态。

王牌飞行员_里海的博客 1982

网络流之最小费用最大流(dinic+SPFA 模板)

【代码】网络流之最小费用最大流(dinic+SPFA 模板)

2301_81488029的博客 466

药物对接仿真软件:HADDOCK_(5).HADDOCK中蛋白质-配体对接流程

半柔性能量最小化阶段是在刚体能量最小化的基础上,允许配体的部分柔性,通过优化配体的构象来进一步提高对接的准确性。半柔性能量最小化阶段是在刚体能量最小化的基础上,允许配体的部分柔性,通过优化配体的构象来进一步提高对接的准确性。如果是PDB格式,确保文件包含所有必要的原子信息。对接完成后,HADDOCK会生成一系列的输出文件,包括对接后的蛋白质-配体复合物结构文件、能量评分文件和统计分析文件。对接完成后,HADDOCK会生成一系列的输出文件,包括对接后的蛋白质-配体复合物结构文件、能量评分文件和统计分析文件。

kkchenjj的博客 1081

【图论】最大流之EK算法与Dinic算法及最小费用最大流

最大流: 给出一张网络图,并指定源点和终点,每条边都有它的容量,起点有着无限的流量,求从源点到经过的所有路径的最终到达汇点的最大流量和。对于同一个节点,流入的流量之和和流出的流量之和相同,即假如结点1有12流量流入结点2,结点2分别有8流量流入结点3,4流量流入结点4,这种情况是可以的。  EK算法: 而EK算法反复寻找源点s到汇点t之间的增广路径,若有,找出增广路径上每一段[容量-

Mankind的博客 2687

ROM和RAM在单片机程序运行理解

ROM和RAM是电子设备中两种核心存储组件,主要区别在于:ROM用于长期存储系统程序、用户文件等固定数据,断电后数据不丢失,但写入速度较慢;RAM则用于临时存储运行中的程序和数据,读写速度快但断电后数据会清空。在单片机中,ROM存储程序代码和常量,RAM存储运行时的变量和数据。两者协同工作,ROM如同"永久档案库"保存必要信息,RAM则像"临时工作台"支持高速运算,共同确保设备正常运行。

qq_37999850的博客 1620

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

【图论】最小费用最大流(网络流进阶)

本文 前置基础:最大流问题(Dinic算法) && 单源最短路径(SPFA算法) 洛谷 P3381 【模板】最小费用最大流 所谓最小费用最大流,其实就是在最大流问题的基础上,再给边加上一个属性:单位流量的费用。边的容量为cap,单位流量的费用为cost,需要求出在最大流的前提下,最小的总费用。(总流量最大并且总费用最小) 每条增广路上的费用 = 这条路上的最小流量 * 所有边的单位流量费用之和。 从原先Dinic算法的模板来看(最大流Dinic模板),有BFS来求分层图,并DFS进行增广。 现在我们需要

nefu_ljw的博客 3532

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

网络流(最大流,dininc,费用流,上下界网络流)

最大流EK算法: Dinic算法: c++98 dinic 费用流c++14 有负边的费用流

m0_51028279的博客 600

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

hdu 4494 Teamwork (可行流的最小流)

去年通话邀请赛的B题,当时竟然过的那么少。。。明明是一道很裸的可行流最小流麽。。只要对每种人分别求一下可行最小流加起来就可以了。建图是对每个点拆点,容量上下届都设为v[i],然后每个点间能连边的直接连边就可以了。然后在这个图的基础上转化为可行流最小流,求一下就可以了。。。 #include #include #include #include #include #include #inclu

ok_again的专栏 1521

hdu 4494 Teamwork(多源多汇最小费用最大流,巧妙构图)

Teamwork Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others) Total Submission(s): 450    Accepted Submission(s): 229 Problem Description Some locations in c

TUT我好菜啊 5840

Hdu 4494 Teamwork(最小费用流)

题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=4494 思路:每种属性人互不干扰,跑m次费用流,结果累加。超级源点0,超级汇点2*n-1。将每个点拆成两个点一个为自己,另一个表示可以提供给别人。源点向每个表示自己的点连一条容量为INF,费用为1的边,表示起点有无数人每选择一人需花费1。对于每个拆出来的点,源点向其连一条容量为kind[i](第i中需

哆啦AC梦的博客 1216

hdu4494

题意:       给你一些任务,每个任务有自己的开始时间和需要多久能干完,还有就是每个任务都需要一些人,这些人有最多五个种类,各种类之间的人不能相互替换,但是某些工人干完这个活后如果可以在另一个任务还没开始的时候赶过去,也可以帮那个任务干活,干的是自己的属性的活,还有一个关键的点就是所有的任务必须人齐了才能干,最后问你最少要多少个人能把活干完.. 思路:       费用流,就是在满流

天使也掉毛 812

hdu 4494 Teamwork 网络流

网上比较多的代码都是用费用流做的,但是这个题目简单的描述就是求最小路径覆盖,每个点覆盖的次数不是1了而已。简单修改求最小路径覆盖的方法即可,源点向顶点,顶点向汇点连的边都变成点需要被覆盖的次数即可。 #include #include #include using namespace std; const int maxn=15e1+9,inf=1e9; int n,m; int su

yrleep的专栏 1108

HDU 4494 - Teamwork(最大流)

题目: http://acm.hdu.edu.cn/showproblem.php?pid=4494 题意: n个任务,m种人,给出起点,以及n-1个点的 坐标,任务的开始时间,持续时间,以及每种人需要的人数。同一个人可以完成多种任务,但必须在开始时间之前到达,求出完成所有的任务最少需要多少人。 思路: 建立源点s,汇点t,拆点i,i+n,可以将人转移的两个任务连边(i,j+n),跑最大

Halo 614

hdu 4494 通化邀请赛B 费用流

去年时还是渣渣中的渣渣。。只记得比赛的时候过这个题的不过,今天拿来做一做发现构图还是挺简单的。 首先要突破的就是5种工人是相互独立的,因为每一个任务的起始和终止时间是固定的,我们用费用流的话又可以保证每个任务都完成(满足最大流),那么每种工人怎么跑是互不影响的,所以做m次费用流,结果为之和。 我的构图有2*n个点,起点为0,终点为2*n-1 流量表示工人数量。 每个维修点拆成两个点,但是和

大风车 708

hdu 4494 Teamwork(费用流)

最开始我是想的,把每个点拆成m个点,然后用一次费用流搞,对于那些可以重复利用的工人,添加一些cost为-1的弧。很逼真把,Why wa。。。 其实每个兵种是相互独立的,那么就可以对于每个兵种,分别搞一次费用流,最后累加ans。这样代码就好撸很多了呢。。。 费用流建图:显然每个点要拆成两个点,一个入(从s向其连的弧,简称x点),一个出(从该点向t连的弧,简称y点)。那么对于i,j两个点,如果en

diary_yang的专栏 1683

【模板】网络流相关

网络流是 acm 竞赛中的一种题型,一般流程是:建出图论模型,之后直接使用板子跑最大流、费用流等。通常有着数据范围小、建模较难看出的特点,需要做题人有一定经验。同时,这种题目对代码能力的要求,则仅限于板子。本文中将举出作者的一些板子,阅读需要有一定的网络流基础,如有不对的地方也欢迎大家斧正。

ararakitsukihi的博客 486
上一篇: HDU 6107 Typesetting(ST)
下一篇: HDU 6135 Casual Podracing(CDQ分治)
v5zsq
博客等级 码龄11年 501粉丝 2436原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值