Shoot the Bullet(有源汇带上下界最大流)
有源汇带上下界最大流
在原图基础上连一条汇点到源点流量为inf的边,将有源汇网络流转化为无源汇网络流用相同方法判断是否满流,如果满流再跑一边源点到汇点的最大流就是答案
例题:Shoot the Bullet 东方文花帖
题目传送门
#include <bits/stdc++.h>
using namespace std;
/* freopen("k.in", "r", stdin);
freopen("k.out", "w", stdout); */
// clock_t c1 = clock();
// std::cerr << "Time:" << clock() - c1 <<"ms" << std::endl;
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#define de(a) cout << #a << " = " << a << endl
#define rep(i, a, n) for (int i = a; i <= n; i++)
#define per(i, a, n) for (int i = n; i >= a; i--)
#define ls ((x) << 1)
#define rs ((x) << 1 | 1)
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
typedef vector<int, int> VII;
#define inf 0x3f3f3f3f
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll MAXN = 2e3 + 7;
const ll MAXM = 1e5 + 7;
const ll MOD = 1e9 + 7;
const double eps = 1e-6;
const double pi = acos(-1.0);
int cnt = -1, head[MAXM], dis[MAXN], cur[MAXM];
int n, m;
struct Edge
{
int to, v, net;
Edge(int _to = 0, int _v = 0, int _net = 0) { to = _to, v = _v, net = _net; }
} e[MAXM << 1]; ///共有n*2条边
void add_edge(int from, int to, int v)
{ ///链式前向星
e[++cnt] = Edge(to, v, head[from]);
head[from] = cnt;
e[++cnt] = Edge(from, 0, head[to]);
head[to] = cnt;
}
int bfs(int st, int ed)
{ ///建立层次图
queue<int> que;
memset(dis, -1, sizeof(dis));
dis[st] = 0;
que.push(st);
while (!que.empty())
{
int x = que.front();
que.pop();
for (int i = head[x]; ~i; i = e[i].net)
{
int now = e[i].to;
if (dis[now] == -1 && e[i].v)
{
que.push(now);
dis[now] = dis[x] + 1;
}
}
}
return dis[ed] != -1;
}
int dfs(int x, int t, int maxflow)
{
if (x == t)
return maxflow;
int ans = 0;
for (int i = cur[x]; ~i; i = e[i].net)
{ ///当前弧优化
int now = e[i].to;
if (dis[now] != dis[x] + 1 || e[i].v == 0 || ans >= maxflow)
continue;
cur[x] = i;
int f = dfs(now, t, min(e[i].v, maxflow - ans));
e[i].v -= f;
e[i ^ 1].v += f; ///反向边加流量
ans += f;
}
if (!ans)
dis[x] = -1; ///炸点优化
return ans;
}
int Dinic(int st, int ed)
{
int ans = 0;
while (bfs(st, ed))
{
memcpy(cur, head, sizeof(head));
int k;
while ((k = dfs(st, ed, inf)))
ans += k;
}
return ans;
}
int totflow[MAXN];
int ans[MAXM];
int lowf[MAXN];
void init()
{
cnt = -1;
memset(head, -1, sizeof(head));
memset(totflow, 0, sizeof(totflow));
memset(lowf, 0, sizeof(lowf));
}
int day[MAXN], girl[MAXN];
int main()
{
while (~scanf("%d%d", &n, &m))
{
init();
int st = 0, ed = n + m + 1;
for (int i = 1; i <= m; i++)
{
scanf("%d", &girl[i]);
totflow[n + i] -= girl[i];
totflow[ed] += girl[i];
}
int tot = 0;
for (int i = 1; i <= n; i++)
{
int c, d;
scanf("%d%d", &c, &day[i]);
for (int j = 1; j <= c; j++)
{
int t, l, r;
scanf("%d%d%d", &t, &l, &r);
++t;
lowf[++tot] = l;
totflow[i] -= l;
totflow[n + t] += l;
add_edge(i, n + t, r - l);
}
}
for (int i = 1; i <= m; i++)
add_edge(n + i, ed, inf);
for (int i = 1; i <= n; i++)
add_edge(st, i, day[i]);
add_edge(ed, st, inf);
int ss = n + m + 2, tt = n + m + 3;
int sumflow = 0;
for (int i = 0; i <= n + m + 1; i++)
{
if (totflow[i] < 0)
add_edge(i, tt, -totflow[i]);
else if (totflow[i] > 0)
{
sumflow += totflow[i];
add_edge(ss, i, totflow[i]);
}
}
if (Dinic(ss, tt) == sumflow)
{
printf("%d\n", Dinic(st, ed));
for (int i = 1; i <= tot; i++)
printf("%d\n", e[((i - 1) << 1) | 1].v + lowf[i]);
}
else
printf("-1\n");
printf("\n");
}
return 0;
}
Shoot the Bullet(有源汇带上下界最大流)的更多相关文章
- ZOJ3229 Shoot the Bullet(有源汇的上下界最大流)
#pragma warning(disable:4996) #include <iostream> #include <cstring> #include <string ...
- zoj3229 Shoot the Bullet(有源汇有上下界的最大流)
题意: 一个屌丝给m个女神拍照,计划拍照n天,每一天屌丝给给定的C个女神拍照,每天拍照数不能超过D张,而且给每个女神i拍照有数量限制[Li,Ri],对于每个女神n天的拍照总和不能少于Gi,如果有解求屌 ...
- LOJ116 - 有源汇有上下界最大流
原题链接 Description 模板题啦~ Code //有源汇有上下界最大流 #include <cstdio> #include <cstring> #include & ...
- 【Loj116】有源汇有上下界最大流(网络流)
[Loj116]有源汇有上下界最大流(网络流) 题面 Loj 题解 模板题. #include<iostream> #include<cstdio> #include<c ...
- loj #116. 有源汇有上下界最大流
题目链接 有源汇有上下界最大流,->上下界网络流 注意细节,重置cur和dis数组时,有n+2个点 #include<cstdio> #include<algorithm> ...
- loj #117. 有源汇有上下界最小流
题目链接 有源汇有上下界最小流,->上下界网络流 注意细节,边数组也要算上后加到SS,TT边. #include<cstdio> #include<algorithm> ...
- LOJ.117.[模板]有源汇有上下界最小流(Dinic)
题目链接 有源汇有上下界最小流 Sol1. 首先和无源汇网络流一样建图,求SS->TT最大流: 然后连边(T->S,[0,INF]),再求一遍SS->TT最大流,答案为新添加边的流量 ...
- [poj] 2396 [zoj] 1994 budget || 有源汇的上下界可行流
poj原题 zoj原题 //注意zoj最后一行不要多输出空行 现在要针对多赛区竞赛制定一个预算,该预算是一个行代表不同种类支出.列代表不同赛区支出的矩阵.组委会曾经开会讨论过各类支出的总和,以及各赛区 ...
- 【LOJ116】有源汇有上下界最大流(模板题)
点此看题面 大致题意: 给你每条边的流量上下界,让你先判断是否存在可行流.若存在,则输出最大流. 无源汇上下界可行流 在做此题之前,最好先去看看这道题目:[LOJ115]无源汇有上下界可行流. 大致思 ...
随机推荐
- Cortex-A8/A76
Cortex-A8 关于Cortex-A8的微处理架构参考<ARM_Cortex-A8微处理器的架构和实现> 其中关于NEON有两段话摘录如下: NEON媒体引擎拥有自己的10段流水线,它 ...
- .NET进阶篇07-.NET和COM
知识需要不断积累.总结和沉淀,思考和写作是成长的催化剂 内容目录 一.COM和.NET元数据内存管理接口注册线程编组二..NET客户端调用COM组件三.COM客户端调用.NET组件四.嵌入互操作类型五 ...
- Android CTS中neverallow规则生成过程
CTS里面SELinux相关测试中neverallow测试项占绝大多数,Android系统开发者都应该知道,在修改sepolicy时,需要确保不能违反这些neverallow规则,不然会过不了CTS. ...
- 记录我的 python 学习历程-Day11 两个被忽视的坑、补充知识点、函数名的应用、新版格式化输出、迭代器
补充知识点 函数形参中默认参数的陷阱 针对不可变数据类型,它是没有陷阱的 def func(name, sex='男'): print(name) print(sex) func('Dylan') # ...
- CentOs7.X下配置FTP
https://blog.csdn.net/cc_want/article/details/85337241 CentOS7.x自带firewall防火墙,FTP使用需要开启20 21 22 3000 ...
- win10开启我的第一个32位汇编程序
遥想当年,上学期间,汇编程序,从未成功.今又试之,终成功,遂记录. Hello.asm文件如下: . .model flat,stdcall option casemap:none include w ...
- Pillow库来着
第一步肯定是安装啦 pip install pillow 如果安装报错,可以升级一下pip库,因为有可能是pip版本低了......... pip show pip 升级用 python -m pip ...
- 1074 宇宙无敌加法器 (20分)C语言
地球人习惯使用十进制数,并且默认一个数字的每一位都是十进制的.而在 PAT 星人开挂的世界里,每个数字的每一位都是不同进制的,这种神奇的数字称为"PAT数".每个 PAT 星人都必 ...
- 阿里云函数计算 .NET Core 初体验
体验了一波阿里云函数计算, 已支持 .NET Core 2.1, 那么按照惯例, 来写个 "Hello World" 吧. 作者注: 开发环境 Windows 10 & V ...
- docker+mysql 构建数据库的主从复制
docker+mysql 构建数据库的主从复制 在最近的项目中,决定将项目改造成数据库读写分离的架构,后续会有博文详细讲述我的开发改造,本文主要记录我是如何一步步的构建数据库的主从复制. 为什么使用d ...