首页 > 其他分享 >费用流

费用流

时间:2022-11-24 13:00:59浏览次数:54  
标签:费用 int cap vis ans dis

title: 费用流
tags: 算法

本文章遵守知识共享协议 CC-BY-NC-SA ,转载时需要署名,推荐在我的个人博客阅读。

简介

费用流是网络流的拓展,一般用于求解一些多次取点的问题。

前置知识

  • 网络流
  • 最短路

讲解

定义

在网络流中,在花费费用最小时的最大流。

如果有冲突,则优先满足最大流。

实现

大体逻辑和网络流区别不大,只是将算法中的 bfs 改为spfa或其他最短路算法,以费用为边权搜索最短路。

费用流算法可以基于 EKDinic 改来,下面这一版是基于 Dinic 更改而来的。

bool spfa(int s, int t) {
  memset(dis, 0x3f, sizeof(dis)); // 初始化距离数组
  memcpy(cur, lnk, sizeof(lnk)); // 复制数组状态
  queue<int> q;  // 正常的spfa
  q.push(s), dis[s] = 0, vis[s] = 1;
  while (!q.empty()) {
    int u = q.front();
    q.pop(), vis[u] = 0;
    for (int i = lnk[u]; i; i = nxt[i]) {
      int v = ter[i];
      if (cap[i] && dis[v] > dis[u] + cost[i]) {
        dis[v] = dis[u] + cost[i];
        if (!vis[v]) q.push(v), vis[v] = 1;
      }
    }
  }
  return dis[t] != INF; // 代表是否可以到达汇点
}

int dfs(int u, int t, int flow) {
  if (u == t) return flow;
  vis[u] = 1;
  int ans = 0;
  for (int &i = cur[u]; i && ans < flow; i = nxt[i]) {
    int v = ter[i];
    if (!vis[v] && cap[i] && dis[v] == dis[u] + cost[i]) {
      int x = dfs(v, t, min(cap[i], flow - ans));
      if (x)
        ret += x * cost[i], 
        cap[i] -= x,
        cap[i ^ 1] += x, ans += x;
    }
  }
  vis[u] = 0;
  return ans;
}

int solve(int s, int t) {
  int ans = 0;
  while (spfa(s, t)) {
    int x;
    while ((x = dfs(s, t, INF))) ans += x;
  }
  return ans;
}

例题

P1004-[NOIP2000-提高组]-方格取数

这道题的难点在于构建费用流网络,首先分析题目性质:

  • 一个格子只能取一次数字
  • 可以走多次

根据这些可以构建出第一个图:

在每个点的连接处连流量为 $2$ ,费用为 $-val_i$ 的边,然后跑最大流。

第一种思路

先别急着翻到下面去,这个构建方法显然是错误的,因为没有考虑到走的次数,并且一个点可能被统计多次。

所以便有了下面这种方法。

我们使用拆点的方法,将一个点拆成两个,点中间连接流量为 $2$,费用为 $-val_i$ 的边,然后跑最大流。

优化后的思路

当然,它还是错的。

继续想更正思路,我们需要再次拆S,T点并添加限流才能确保没问题。

还有一点就是像 1->1' 这里要连两条边,第一条容量 $1$ 费用 $0$ 确保联通,第二条容量 $1$ 费用 $-val_i$ 才是实际能取到的价值

最后构建出的图

最后的图就是这样。

其实不管是网络流,还是费用流,最难的部分都是构建图,需要多理解为什么这么构建才能。

P1000-A+B-Problem

同样简单的讲解一下。

标签:费用,int,cap,vis,ans,dis
From: https://www.cnblogs.com/rickyxrc/p/16921522.html

相关文章

  • Dinic(最大流/最小割+费用流)
    最大流/最小割:1typedeflonglongll;2constintN=1e4+5;3constintM=2e5+5;4constllinf=1e18;5intn,m,s,t,tot;6llhead[N],to[......
  • HCIE有没有必要重认证?hcie重认证费用是多少?
    HCIE重认证规则HCIE系列认证是华为职业认证中用于标识个人能力在某一技术领域达到专家级别的证明。HCIE证书的有效期是两年,重认证之后的有效期是两年。详细了解华为认证重......
  • 最高法-承包人放弃费用索赔要求不能解释为放弃对违约责任的追究
    (2020)最高法民终941号  湖南建工集团有限公司、贵州高速公路集团有限公司建设工程施工合同纠纷二审民事裁定书关键词:索赔时限 建设工程 违约责任 放弃本院认为:......
  • 【CF802O】April Fools‘ Problem (hard)(wqs二分,模拟费用流,老鼠进洞)
    如果没有恰好为\(k\)的限制的话是个老鼠进洞的经典模型。加上恰好为\(k\)的限制后考虑使用wqs二分,因为费用流每次增广出来的费用是单调不降的。即如果设\(g(k)\)......
  • 【BZOJ2502】清理雪道(最大费用最大流)
    上下界网络流的做法大佬们都讲过了,我就来讲一个另类的解法。(不过也是网络流)这个做法是考场上想了很久都不会后奇思妙想想出来的(不会上下界网络流),所以没多少思路引导。首......
  • CF 237E(字母选取-费用流)
    题目大意:有一字符串S,你需要从n个字符串中选取一些来拼出这个串,第i个字符串代价为i,限制取P次,问最小代价(无解输出-1)建立超源S=0,超汇T=n+26+1 1-n的结点为字符串n+1-n+26的......
  • BZOJ 2661([BeiJing wc2012]连连看-费用流)
    Description凡是考智商的题里面总会有这么一种消除游戏。不过现在面对的这关连连看可不是QQ游戏里那种考眼力的游戏。我们的规则是,给出一个闭区间[a,b]中的全部整数,如果其中......
  • Heidi and Library (hard) | CodeForces 802C最大流最小费用
    神仙题,想了两节ds课没想出来,跑到奇怪的犄角旮旯去了还是没法搞一个满意的模型看了洛谷黑题啊..释然了思路和细节在代码//LUOGU_RID:90857083#include<bits/stdc++.h......
  • acwing 二维费用的背包问题
    题面有N件物品和一个容量是V的背包,背包能承受的最大重量是M。每件物品只能用一次。体积是vi,重量是mi,价值是wi。求解将哪些物品装入背包,可使物品总体积不超过背......
  • 工厂MES系统功能与MES系统开发费用明细介绍
    在如今数智化时代,各行各业都在发生着巨大的变化,智能制造已逐步深入到制造业之中,工厂已进入高效生产时代。MES系统的出现,为制造业提供了全方位高效生产管理模式,可对人、设备......