题目地址:P4553 80人环游世界

上下界网络流

无源汇上下界可行流

给定 \(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\) 的边,把汇流入的流量转移给源流出的流量,转化为无源汇的网络,然后求解无源汇上下界可行流

有源汇上下界最小费用可行流

类似有源汇上下界可行流,求最大流改为求最小费用最大流。

每个国家拆成两个点(入点 \(i\) 和出点 \(i+n\)),建立源 \(s\) 汇 \(t\) 附加源 \(s\_\) 。

连边:

  1. \((s,s\_,m,m,0)\) ;
  2. \((s\_,i,0,m,0)\) ;
  3. \((i+n,t,0,m,0)\) ;
  4. \((i,i+n,V[i],V[i],0)\) ;
  5. 若 \(i,j\) 两个国家通航,连边 \((i+n,j,0,m,Cost_{i,j})\) 。

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

#include <bits/stdc++.h>
using namespace std;
const int N = 206, M = 1e5 + 6, inf = 0x3f3f3f3f;
int n, m, S, T, s, s_, t, d[N], now[N], pre[N], ans;
int Head[N], Edge[M], Leng[M], Cost[M], Next[M], tot = 1;
bitset<N> v;

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

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

inline bool spfa() {
    v.reset();
    memset(d, 0x3f, sizeof(d));
    queue<int> q;
    q.push(S);
    v[S] = 1;
    d[S] = 0;
    now[S] = m;
    while (q.size()) {
        int x = q.front();
        q.pop();
        v[x] = 0;
        for (int i = Head[x]; i; i = Next[i]) {
            int y = Edge[i], z = Leng[i], w = Cost[i];
            if (!z || d[y] <= d[x] + w) continue;
            d[y] = d[x] + w;
            now[y] = min(now[x], z);
            pre[y] = i;
            if (!v[y]) {
                q.push(y);
                v[y] = 1;
            }
        }
    }
    return d[T] != inf;
}

inline void upd() {
    ans += d[T] * now[T];
    int x = T;
    while (x != S) {
        int i = pre[x];
        Leng[i] -= now[T];
        Leng[i^1] += now[T];
        x = Edge[i^1];
    }
}

int main() {
    cin >> n >> m;
    s = n * 2 + 1, s_ = s + 1, t = s_ + 1;
    S = t + 1, T = S + 1;
    ins(s, s_, m, m, 0);
    for (int i = 1; i <= n; i++) {
        ins(s_, i, 0, m, 0);
        ins(i + n, t, 0, m, 0);
        int x;
        scanf("%d", &x);
        ins(i, i + n, x, x, 0);
    }
    for (int i = 1; i <= n; i++)
        for (int j = i + 1; j <= n; j++) {
            int x;
            scanf("%d", &x);
            if (~x) ins(i + n, j, 0, m, x);
        }
//  ins(t, s, 0, m, 0);
    for (int i = 1; i <= t; i++) {
        if (d[i] > 0) add(S, i, d[i], 0);
        else if (d[i] < 0) add(i, T, -d[i], 0);
    }
    while (spfa()) upd();
    cout << ans << endl;
    return 0;
}

注意:代码中注释的那一条语句加不加都可以AC,具体原因有待研究(讨论

P4553 80人环游世界的更多相关文章

  1. P4553 80人环游世界(上下界费用流)

    P4553 80人环游世界 emm......先从上下界网络流(转)开始 再到现在的上下界费用流 因为有上下界,我们需要记下每个点的流量差$ex[i]$,用于调整 $ins(x,y,l,r,v)=li ...

  2. 洛谷P4553 80人环游世界

    题目描述 https://www.luogu.org/problemnew/show/P4553 题解 思路比较显然,把图建出来,一个国家拆成两个点,中间设置上下界,然后跑费用流. 我把源那边的流量也 ...

  3. Luogu P4553 80人环游世界

    link 题目大意 自东向西有 \(n\) 个国家.有 \(m\) 个人,他们可以选择 \(n\) 个国家中任意一个开始,任意一个结束,但路线必须自东向西,且第 \(i\) 个国家必须恰好经过 \(v ...

  4. 【BZOJ-2055】80人环游世界 上下界费用流 (无源无汇最小费用最大流)

    2055: 80人环游世界 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 321  Solved: 201[Submit][Status][Discus ...

  5. BZOJ2055: 80人环游世界

    题解: 总算A掉了,各种蛋疼... int main() { freopen("input.txt","r",stdin); freopen("out ...

  6. BZOJ 2055: 80人环游世界 [上下界费用流]

    2055: 80人环游世界 题意:n个点带权图,选出m条路径,每个点经过val[i]次,求最小花费 建图比较简单 s拆点限制流量m 一个点拆成两个,限制流量val[i],需要用上下界 图中有边的连边, ...

  7. [BZOJ2055]80人环游世界 有上下界最小费用最大流

    2055: 80人环游世界 Time Limit: 10 Sec  Memory Limit: 64 MB Description     想必大家都看过成龙大哥的<80天环游世界>,里面 ...

  8. bzoj 2055: 80人环游世界 -- 上下界网络流

    2055: 80人环游世界 Time Limit: 10 Sec  Memory Limit: 64 MB Description     想必大家都看过成龙大哥的<80天环游世界>,里面 ...

  9. 【BZOJ】2055 80人环游世界

    [算法]有源汇上下界最小费用可行流 [题解]上下界 因为上下界相同,所以无所谓最小流了,可行流(初始流+附加流)就是答案了. 记得源点向新建节点连一条容量为m(人)的边. bzoj 2055 80人环 ...

随机推荐

  1. python自动化开发-[第二天]-基础数据类型与编码(续)

    今日简介: - 编码 - 进制转换 - 初识对象 - 基本的数据类型 - 整数 - 布尔值 - 字符串 - 列表 - 元祖 - 字典 - 集合 - range/enumcate 一.编码 encode ...

  2. Compiling R-3.4.3 on CentOS 6.10 with GNU

    If you are compiling CentOS 6, you will notice that the R source will not compile without a updated ...

  3. ASP.NET的checkboxlist,RadioButtonList,FileUpload,image控件的综合使用

    一.拖控件 控件拖完如图所示:(有些是对不齐的,加一个表单就好了,把他们都放在表单里) 单纯的RadioButton是不能只选择一个的,除非你手动给他们加上代码: RadioButton1.Group ...

  4. CentOS7 下 Hadoop 单节点(伪分布式)部署

    Hadoop 下载 (2.9.2) https://hadoop.apache.org/releases.html 准备工作 关闭防火墙 (也可放行) # 停止防火墙 systemctl stop f ...

  5. ByteBuffer详解

    注意:一定要了解这个缓冲类的几个方法和那几个字段.不然你不会明白的. 字段: position ,limit ,mark 方法:clear(), hasRemaining(),flip() 推荐博客: ...

  6. SQL Server 备份到网络盘网络映射盘

    declare @DBName nvarchar(max) declare @BakName nvarchar(max) --在这里修改数据库名称 select @DBName='[LFBMP.PO] ...

  7. canvas加载图片需要二次刷新的问题

    如题:此问题我也经在百度问问上进行了解答.https://zhidao.baidu.com/question/1048045241465845579.html 好吧,难怪现在百度那么坑人,理论水军专家 ...

  8. Trailing slash

    Trailing Slash common case It's common for URLs with a trailing slash to indicate a directory, and t ...

  9. 039、Data Volume 之 bind mount (2019-02-28 周四)

    参考https://www.cnblogs.com/CloudMan6/p/7142150.html     Date Volume 本质上是Dokcer host文件系统中的目录或者文件,能够直接被 ...

  10. 细说java系列之泛型

    什么是范型 简言之,范型是Java支持在编译期进行类型检查的机制. 这里面包含2层含义:其一,可以使用范型进行类型检查:其二,在编译期进行类型检查. 那么,什么叫做在编译期进行类型检查?可以在运行时进 ...