有源汇带上下界最大流

在原图基础上连一条汇点到源点流量为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(有源汇带上下界最大流)的更多相关文章

  1. ZOJ3229 Shoot the Bullet(有源汇的上下界最大流)

    #pragma warning(disable:4996) #include <iostream> #include <cstring> #include <string ...

  2. zoj3229 Shoot the Bullet(有源汇有上下界的最大流)

    题意: 一个屌丝给m个女神拍照,计划拍照n天,每一天屌丝给给定的C个女神拍照,每天拍照数不能超过D张,而且给每个女神i拍照有数量限制[Li,Ri],对于每个女神n天的拍照总和不能少于Gi,如果有解求屌 ...

  3. LOJ116 - 有源汇有上下界最大流

    原题链接 Description 模板题啦~ Code //有源汇有上下界最大流 #include <cstdio> #include <cstring> #include & ...

  4. 【Loj116】有源汇有上下界最大流(网络流)

    [Loj116]有源汇有上下界最大流(网络流) 题面 Loj 题解 模板题. #include<iostream> #include<cstdio> #include<c ...

  5. loj #116. 有源汇有上下界最大流

    题目链接 有源汇有上下界最大流,->上下界网络流 注意细节,重置cur和dis数组时,有n+2个点 #include<cstdio> #include<algorithm> ...

  6. loj #117. 有源汇有上下界最小流

    题目链接 有源汇有上下界最小流,->上下界网络流 注意细节,边数组也要算上后加到SS,TT边. #include<cstdio> #include<algorithm> ...

  7. LOJ.117.[模板]有源汇有上下界最小流(Dinic)

    题目链接 有源汇有上下界最小流 Sol1. 首先和无源汇网络流一样建图,求SS->TT最大流: 然后连边(T->S,[0,INF]),再求一遍SS->TT最大流,答案为新添加边的流量 ...

  8. [poj] 2396 [zoj] 1994 budget || 有源汇的上下界可行流

    poj原题 zoj原题 //注意zoj最后一行不要多输出空行 现在要针对多赛区竞赛制定一个预算,该预算是一个行代表不同种类支出.列代表不同赛区支出的矩阵.组委会曾经开会讨论过各类支出的总和,以及各赛区 ...

  9. 【LOJ116】有源汇有上下界最大流(模板题)

    点此看题面 大致题意: 给你每条边的流量上下界,让你先判断是否存在可行流.若存在,则输出最大流. 无源汇上下界可行流 在做此题之前,最好先去看看这道题目:[LOJ115]无源汇有上下界可行流. 大致思 ...

随机推荐

  1. 洛谷$P1712\ [NOI2016]$区间 线段树

    正解:线段树 解题报告: 传送门$QwQ$ $umm$很久以前做的了来补个题解$QwQ$ 考虑给每个区间按权值($r-l$从大往小排序,依次加入,然后考虑如果有一个位置被覆盖次数等于$m$了就可以把权 ...

  2. $Luogu2512/CH122/AcWing122$糖果传递 模拟

    $Luogu$  $AcWing$ $Description$ 有$n$个小朋友坐成一圈,每人有$a_i$个糖果. 每人只能给左右两人传递糖果. 每人每次传递一个糖果代价为$1$. 求使所有人获得均等 ...

  3. SQL MAX()函数处理字符型字段

    假设有数据库表student,表中有字段studentCode,它是字符型的,现有需求:“每次向student表插入数据时,自动生成studentCode字段的值” 如果你的实现思路是这样的: if( ...

  4. JVM探秘:内存分配与回收策略

    本系列笔记主要基于<深入理解Java虚拟机:JVM高级特性与最佳实践 第2版>,是这本书的读书笔记. 内存分配一般关注的是对象在堆上分配的情况,对象主要分配在新生代的Eden区中,如果启用 ...

  5. 1028 人口普查 (20 分)C语言

    题目描述 某城镇进行人口普查,得到了全体居民的生日.现请你写个程序,找出镇上最年长和最年轻的人. 这里确保每个输入的日期都是合法的,但不一定是合理的--假设已知镇上没有超过200岁的老人,而今天是20 ...

  6. docker-bind挂载

    使用绑定挂载 自Docker早期以来,绑定挂载一直存在.与卷相比,绑定装载具有有限的功能.使用绑定装入时,主机上的文件或目录将装入容器中.文件或目录由其在主机上的完整路径或相对路径引用.相反,当您使用 ...

  7. 基于CentOS 7 部署MySQL 5.7的基本操作

    关闭selinux # sed -i '/SELINUX/s/enforcing/disabled/' /etc/selinux/config重启后生效# sestatus 修改提示符配置# vi / ...

  8. python列表的方法(改变原列表)

    xxx.append()      末尾添加一个元素效果图: 代码: # append() 末尾添加一个元素 my_list = ['] print('原列表:',my_list) my_list.a ...

  9. 常见基本数据结构——树,二叉树,二叉查找树,AVL树

    常见数据结构——树 处理大量的数据时,链表的线性时间太慢了,不宜使用.在树的数据结构中,其大部分的运行时间平均为O(logN).并且通过对树结构的修改,我们能够保证它的最坏情形下上述的时间界. 树的定 ...

  10. 如何设计一个优雅的RESTFUL的接口

    show me the code and talk to me,做的出来更要说的明白 我是布尔bl,你的支持是我分享的动力! 一 .引入 设计接口是我们开发人员的日常操作.当我们把接口交给前端人员时, ...