P4843 清理雪道
题目地址: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\) 的边,把汇流入的流量转移给源流出的流量,转化为无源汇的网络,然后求解无源汇上下界可行流。
有源汇上下界最小流
两个方法:
- 二分答案 \(ans\) ,从 \(T\) 到 \(S\) 连一条下界为 \(0\) ,上界为 \(ans\) 的边,转化为无源汇网络。找到最小的 \(ans\) ,使得该无源汇上下界网络有可行流。
- 类似有源汇上下界可行流的构图方法,但先不添加 \(T\) 到 \(S\) 的边,求一次超级源到超级汇的最大流。然后再添加一条从 \(T\) 到 \(S\) 下界为 \(0\) ,上界为 \(+inf\) 的边,在残量网络上再求一次超级源到超级汇的最大流。流经 \(T\) 到 \(S\) 的边的流量就是最小流的值。该算法的思想是在第一步中尽可能填充循环流,以减小最小流的代价。
连边:
- \((s,i,0,+inf)\) ;
- \((i,t,0,+inf)\) ;
- 对每条雪道,连边 \((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 清理雪道的更多相关文章
- P4843 清理雪道(上下界网络流)
P4843 清理雪道 上下界最小流 我们先搞一遍上下界可行流(转) 回忆上下界最大流的写法:在可行流的残量网络$s\ -\ t$上跑最大流,答案为可行流$+$残量网络的最大流 那么上下界最小流的写法呢 ...
- BZOJ 2502 Luogu P4843 清理雪道 最小流
题意: 滑雪场坐落在FJ省西北部的若干座山上. 从空中鸟瞰,滑雪场可以看作一个有向无环图,每条弧代表一个斜坡(即雪道),弧的方向代表斜坡下降的方向. 你的团队负责每周定时清理雪道.你们拥有一架直升飞机 ...
- 洛谷P4843 清理雪道
题意:给你DAG,求最小路径边覆盖.路径可重. 解:首先可以想到边转点,发现有n²条边,果断超时. 有源汇有上下界最小流. 建图:每条边都建立一条边,流量限制为[1, 1]. 源点向每个点连边,因为都 ...
- BZOJ 2502 清理雪道/ Luogu P4843 清理雪道 (有源汇上下界最小流)
题意 有一个有向无环图,求最少的路径条数覆盖所有的边 分析 有源汇上下界最小流板题,直接放代码了,不会的看dalao博客:liu_runda 有点长,讲的很好,静心看一定能看懂 CODE #inclu ...
- luogu P4843 清理雪道
嘟嘟嘟 这其实就是一个最小流的板子题.把每一条边的流量至少为1,然后建立附加源汇跑一遍最大流,连上\(t, s\),再跑一遍最大流就是答案. 刚开始我想错了:统计每一个点的出度和入度,去两者较大值\( ...
- 【BZOJ-2502】清理雪道 有上下界的网络流(有下界的最小流)
2502: 清理雪道 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 594 Solved: 318[Submit][Status][Discuss] ...
- [BZOJ2502]清理雪道
[BZOJ2502]清理雪道 试题描述 滑雪场坐落在FJ省西北部的若干座山上. 从空中鸟瞰,滑雪场可以看作一个有向无环图,每条弧代表一个斜坡(即雪道),弧的方向代表斜坡下降的方向. 你的团队负责每周定 ...
- BZOJ 2502: 清理雪道 [最小流]
2502: 清理雪道 题意:任意点出发任意次每条边至少经过一次最小花费. 下界1,裸最小流.... #include <iostream> #include <cstdio> ...
- BZOJ_2502_清理雪道_有源汇上下界最小流
BZOJ_2502_清理雪道_有源汇上下界最小流 Description 滑雪场坐落在FJ省西北部的若干座山上. 从空中鸟瞰,滑雪场可以看作一个有向无环图,每条弧代表一个斜坡(即雪道), ...
随机推荐
- lucene的CRUD操作Document(四)
IndexWriter writer = new IndexWriter(Directory, IndexWriterConfig); 增加文档:writer.addDocument(); 读取文档: ...
- 剑指Offer_编程题_15
题目描述 输入一个链表,反转链表后,输出链表的所有元素. /* struct ListNode { int val; struct ListNode *next; ListNode(int x) : ...
- SQL语法基础之CREATE语句
SQL语法基础之CREATE语句 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.查看帮助信息 1>.使用“?”来查看MySQL命令的帮助信息 mysql> ? CR ...
- Java Web服务收到请求时线程的情况
Web请求线程的状态 在开发中,突然想到了这样的一个问题, Java对每一次Web的请求,是否都会创建一条线程去进行处理呢?也就是说,当一个Class的方法同时有1000个请求访问时,线程是如何运作的 ...
- Java方向如何准备技术面试答案(汇总版)
本文转载自:"Java团长"公众号 1.面向对象和面向过程的区别 面向过程优点:性能比面向对象高,因为类调用时需要实例化,开销比较大,比较消耗资源;比如单片机.嵌入式开发.Linu ...
- DirectX11 With Windows SDK--02 顶点/像素着色器的创建、顶点缓冲区
前言 由于在Direct3D 11中取消了固定管线,要想绘制图形必须要了解可编程渲染管线的流程,一个能绘制出图形的渲染管线最少需要有这两个可编程着色器:顶点着色器和像素着色器. 本章会直接跳过渲染管线 ...
- Python线程和协程-day10
写在前面 上课第10天,打卡: 感谢Egon老师细致入微的讲解,的确有学到东西! 一.线程 1.关于线程的补充 线程:就是一条流水线的执行过程,一条流水线必须属于一个车间: 那这个车间的运行过程就是一 ...
- Echarts地图悬浮框显示多组series数据以及修改地图大小
1.如何让echarts的地图悬浮框出现多组series数据? 2.如何更改地图默认的大小? <!DOCTYPE html> <html lang="en"> ...
- Spring boot 工具类静态属性注入及多环境配置
由于需要访问MongoDB,但是本地开发环境不能直接连接MongoDB,需要通过SecureCRT使用127.0.0.2本地IP代理.但是程序部署到线上生产环境后,是可以直接访问MongoDB的,因此 ...
- SQL Server进阶 窗口函数
概述 设计窗口函数目的? 在开窗函数出现之前存在着很多用 SQL 语句很难解决的问题,很多都要通过复杂的相关子查询或者存储过程来完成. 为了解决这些问题,在 2003 年 ISO SQL 标准加入了 ...