题目地址: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. Linux 中用 dd 命令来测试硬盘读写速度

    dd 是 Linux/UNIX 下的一个非常有用的命令,作用是用指定大小的块拷贝一个文件,并在拷贝的同时进行指定的转换. dd 命令通用语法格式如下: dd if=path/to/input_file ...

  2. vbox的桥接网络

    直接连接到了外网上,宿主机可以访问虚拟机,但是虚拟机不可以访问宿主机.缺点:宿主机没有网络时,将不能ping通. 宿主机:win10 网络:无线 虚拟机系统:centos6.5 vbox版本:6.0. ...

  3. DBMS客户端是否安装:Make sure DBMS client is installed and this required library is available for dynamic loading

    Symptom The full error message is as follows:Error logging in.  Unable to process the database trans ...

  4. WiFi热点(1):windows8建wifi虚拟热点

    在windows8系统中,打开记事本,写入下面两行:@netsh wlan set hostednetwork mode=allow ssid=wuyazhe key=88888888@netsh w ...

  5. Vue.js 循环语句

    循环使用 v-for 指令. v-for 指令需要以 site in sites 形式的特殊语法, sites 是源数据数组并且 site 是数组元素迭代的别名. v-for 指令: v-for 可以 ...

  6. 5.Hystrix-服务降级

    所谓降级,就是当某个服务出现异常之后,服务器将不再被调用,此时服务端可以自己准备一个本地的fallback回调,返回一个缺省值. 这样做,虽然服务水平下降,但好歹可用,比直接挂掉要强,当然这也要看适合 ...

  7. Kafka技术内幕 读书笔记之(二) 生产者——服务端网络连接

    KafkaServer是Kafka服务端的主类, KafkaServer中和网络层有关的服务组件包括 SocketServer.KafkaApis 和 KafkaRequestHandlerPool后 ...

  8. python爬虫慕课基础1

    test_urllib2.py import http.cookiejar from urllib import request url = "http://www.baidu.com&qu ...

  9. Python获取下载速度并显示进度条

    #!/usr/bin/python3 # -*- coding:utf-8 -*- import sys import time from urllib import request ''' urll ...

  10. 用Google Brain的机器学习项目:Magenta,教神经网络学抖音小姐姐作曲。

    先上我们要学习的小姐姐 的美照.. 一.配置环境 1.自己配置环境:python,tensorflow,bazel(编译),java.然后下载magenta(https://github.com/te ...