题目地址:P4843 清理雪道

上下界网络流

无源汇上下界可行流

给定 \(n\) 个点, \(m\) 条边的网络,求一个可行解,使得边 \((u,v)\) 的流量介于 \([B(u,v),C(u,v)]\) 之间,并且整个网络满足流量守恒。

如果把 \(C-B\) 作为容量上界, \(0\) 作为容量下界,就是一般的网络流模型。

然而求出的实际流量为 \(f(u,v)+B(u,v)\) ,不一定满足流量守恒,需要调整。

设 \(inB[u]=\sum B(i,u)\) , \(outB[u]=\sum B(u,i)\) , \(d[u]=inB[u]-outB[u]\) 。

新建源汇, \(S\) 向 \(d>0\) 的点连边, \(d<0\) 的点向 \(T\) 连边,容量为相应的 \(d\) 。

在该网络上求最大流,则每条边的流量 \(+\) 下界就是原网络的一个可行流。

具体实现时,可省略 \(inB,outB\) 数组,直接在 \(d\) 数组上修改。

有源汇上下界可行流

从 \(T\) 到 \(S\) 连一条下界为 \(0\) ,上界为 \(+inf\) 的边,把汇流入的流量转移给源流出的流量,转化为无源汇的网络,然后求解无源汇上下界可行流

有源汇上下界最小流

两个方法:

  1. 二分答案 \(ans\) ,从 \(T\) 到 \(S\) 连一条下界为 \(0\) ,上界为 \(ans\) 的边,转化为无源汇网络。找到最小的 \(ans\) ,使得该无源汇上下界网络有可行流。
  2. 类似有源汇上下界可行流的构图方法,但先不添加 \(T\) 到 \(S\) 的边,求一次超级源到超级汇的最大流。然后再添加一条从 \(T\) 到 \(S\) 下界为 \(0\) ,上界为 \(+inf\) 的边,在残量网络上再求一次超级源到超级汇的最大流。流经 \(T\) 到 \(S\) 的边的流量就是最小流的值。该算法的思想是在第一步中尽可能填充循环流,以减小最小流的代价。

连边:

  1. \((s,i,0,+inf)\) ;
  2. \((i,t,0,+inf)\) ;
  3. 对每条雪道,连边 \((i,j,1,+inf)\) 。

对网络 \(s-t\) 求有源汇上下界最小流

这里使用方法二。

#include <bits/stdc++.h>
using namespace std;
const int N = 106, M = 2e4 + 6, inf = 1e9;
int n, s, t, S, T, d[N], ans;
int Head[N], Edge[M], Leng[M], Next[M], tot = 1;

inline void add(int x, int y, int z) {
    Edge[++tot] = y;
    Leng[tot] = z;
    Next[tot] = Head[x];
    Head[x] = tot;
    Edge[++tot] = x;
    Leng[tot] = 0;
    Next[tot] = Head[y];
    Head[y] = tot;
}

inline void ins(int x, int y, int l, int r) {
    add(x, y, r - l);
    d[x] -= l;
    d[y] += l;
}

inline bool bfs() {
    memset(d, 0, sizeof(d));
    queue<int> q;
    q.push(S);
    d[S] = 1;
    while (q.size()) {
        int x = q.front();
        q.pop();
        for (int i = Head[x]; i; i = Next[i]) {
            int y = Edge[i], z = Leng[i];
            if (d[y] || !z) continue;
            q.push(y);
            d[y] = d[x] + 1;
            if (y == T) return 1;
        }
    }
    return 0;
}

int dinic(int x, int flow) {
    if (x == T) return flow;
    int rest = flow;
    for (int i = Head[x]; i && rest; i = Next[i]) {
        int y = Edge[i], z = Leng[i];
        if (d[y] != d[x] + 1 || !z) continue;
        int k = dinic(y, min(rest, z));
        if (!k) d[y] = 0;
        else {
            Leng[i] -= k;
            Leng[i^1] += k;
            rest -= k;
        }
    }
    return flow - rest;
}

int main() {
    cin >> n;
    s = n + 1, t = n + 2, S = n + 3, T = n + 4;
    for (int i = 1; i <= n; i++) {
        ins(s, i, 0, inf);
        ins(i, t, 0, inf);
        int k;
        scanf("%d", &k);
        while (k--) {
            int x;
            scanf("%d", &x);
            ins(i, x, 1, inf);
        }
    }
    for (int i = 1; i <= t; i++) {
        if (d[i] > 0) add(S, i, d[i]);
        else if (d[i] < 0) add(i, T, -d[i]);
    }
    while (bfs()) while (dinic(S, inf));
    ins(t, s, 0, inf);
    while (bfs()) while (dinic(S, inf));
    cout << Leng[tot] << endl;
    return 0;
}

P4843 清理雪道的更多相关文章

  1. P4843 清理雪道(上下界网络流)

    P4843 清理雪道 上下界最小流 我们先搞一遍上下界可行流(转) 回忆上下界最大流的写法:在可行流的残量网络$s\ -\ t$上跑最大流,答案为可行流$+$残量网络的最大流 那么上下界最小流的写法呢 ...

  2. BZOJ 2502 Luogu P4843 清理雪道 最小流

    题意: 滑雪场坐落在FJ省西北部的若干座山上. 从空中鸟瞰,滑雪场可以看作一个有向无环图,每条弧代表一个斜坡(即雪道),弧的方向代表斜坡下降的方向. 你的团队负责每周定时清理雪道.你们拥有一架直升飞机 ...

  3. 洛谷P4843 清理雪道

    题意:给你DAG,求最小路径边覆盖.路径可重. 解:首先可以想到边转点,发现有n²条边,果断超时. 有源汇有上下界最小流. 建图:每条边都建立一条边,流量限制为[1, 1]. 源点向每个点连边,因为都 ...

  4. BZOJ 2502 清理雪道/ Luogu P4843 清理雪道 (有源汇上下界最小流)

    题意 有一个有向无环图,求最少的路径条数覆盖所有的边 分析 有源汇上下界最小流板题,直接放代码了,不会的看dalao博客:liu_runda 有点长,讲的很好,静心看一定能看懂 CODE #inclu ...

  5. luogu P4843 清理雪道

    嘟嘟嘟 这其实就是一个最小流的板子题.把每一条边的流量至少为1,然后建立附加源汇跑一遍最大流,连上\(t, s\),再跑一遍最大流就是答案. 刚开始我想错了:统计每一个点的出度和入度,去两者较大值\( ...

  6. 【BZOJ-2502】清理雪道 有上下界的网络流(有下界的最小流)

    2502: 清理雪道 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 594  Solved: 318[Submit][Status][Discuss] ...

  7. [BZOJ2502]清理雪道

    [BZOJ2502]清理雪道 试题描述 滑雪场坐落在FJ省西北部的若干座山上. 从空中鸟瞰,滑雪场可以看作一个有向无环图,每条弧代表一个斜坡(即雪道),弧的方向代表斜坡下降的方向. 你的团队负责每周定 ...

  8. BZOJ 2502: 清理雪道 [最小流]

    2502: 清理雪道 题意:任意点出发任意次每条边至少经过一次最小花费. 下界1,裸最小流.... #include <iostream> #include <cstdio> ...

  9. BZOJ_2502_清理雪道_有源汇上下界最小流

    BZOJ_2502_清理雪道_有源汇上下界最小流 Description        滑雪场坐落在FJ省西北部的若干座山上. 从空中鸟瞰,滑雪场可以看作一个有向无环图,每条弧代表一个斜坡(即雪道), ...

随机推荐

  1. Harbor 使用 Helm 一键安装

    安装 Harbor Harbor 支持多种安装方式,源码目录下面默认有一个安装脚本(make/install.sh),采用 docker-compose 的形式运行 Harbor 各个组件,和前面的课 ...

  2. Zookeeper 集群安装配置

    今天,栈长分享下 Zookeeper 的集群安装及配置. 下载 下载地址:http://zookeeper.apache.org/ 下载过程就不说了,我们下载了最新的zookeeper-3.4.11. ...

  3. 在linux下面解压用的zxpf是什么意思,它跟zxvf有啥区别

    在linux下面解压用的zxpf是什么意思,它跟zxvf有啥区别 linux 命令中tar后跟的zxvf是什么意思:.tar.gz是一个压缩包   .tar只是打包而没有压缩 z:表示 tar 包是被 ...

  4. python APScheduler

    简介 APScheduler基于Quartz的一个Python定时任务框架,实现了Quartz的所有功能,使用起来十分方便.提供了基于日期.固定时间间隔以及crontab类型的任务,并且可以持久化任务 ...

  5. docker 私有仓库之Harbor搭建与使用

    Harbor搭建 下载Harbor: http://harbor.orientsoft.cn/ #下载offline版本 配置Harbor tar xvf harbor-online-installe ...

  6. Visual Studio连接到TFS

    我在学校自己使用git,公司使用VSS,然后这个项目又使用TFS.Visual Studio连接到TFS是这样滴 1.点连接到团队项目 2.添加TFS服务器的url,写到你的http:XXX/tfs就 ...

  7. JAVA核心技术I---JAVA基础知识(抽象类和接口)

    一:抽象类 (一)定义 类:属性(0或多个)+方法(0或多个)一个完整(健康)的类:所有的方法都有实现(方法体)类可以没有方法,但是有方法就肯定要有实现,这才是一个完整的类一个完整的类才可以被实例化, ...

  8. C语言复习---找出一个二维数组的鞍点

    前提: 求任意的一个m×n矩阵的鞍点——鞍点是指该位置上的元素在该行上为最大.在该列上为最小, 矩阵中可能没有鞍点,但最多只有一个鞍点. m.n(<=m<=.<=n<=)及矩阵 ...

  9. 使用git 上传项目到gitee/github

    参考: https://blog.csdn.net/qq944639839/article/details/79864081 注意:在此之前需要设置ssh公匙 详见:Github/github 初始化 ...

  10. photoshop 切图技巧

    前端切图技巧 手动切图 参考线切图 精准切图 自动切图 原文地址 http://www.cnblogs.com/w-wanglei/p/5598336.html