Description

Gensokyo is a world which exists quietly beside ours, separated by a mystical border. It is a utopia where humans and other beings such as fairies, youkai(phantoms), and gods live peacefully together. Shameimaru Aya is a crow tengu with the ability to manipulate wind who has been in Gensokyo for over 1000 years. She runs the Bunbunmaru News - a newspaper chock-full of rumors, and owns the Bunkachou - her record of interesting observations for Bunbunmaru News articles and pictures of beautiful danmaku(barrange) or cute girls living in Gensokyo. She is the biggest connoisseur of rumors about the girls of Gensokyo among the tengu. Her intelligence gathering abilities are the best in Gensokyo!

During the coming n days, Aya is planning to take many photos of m cute girls living in Gensokyo to write Bunbunmaru News daily and record at least Gx photos of girl x in total in the Bunkachou. At the k-th day, there are Ck targets, Tk1Tk2, ..., TkCk. The number of photos of target Tki that Aya takes should be in range [LkiRki], if less, Aya cannot write an interesting article, if more, the girl will become angry and use her last spell card to attack Aya. What's more, Aya cannot take more than Dk photos at the k-th day. Under these constraints, the more photos, the better.

Aya is not good at solving this complex problem. So she comes to you, an earthling, for help.

Input

There are about 40 cases. Process to the end of file.

Each case begins with two integers 1 <= n <= 365, 1 <= m <= 1000. Then m integers, G1G2, ..., Gm in range [0, 10000]. Then n days. Each day begins with two integer 1 <= C <= 100, 0 <= D<= 30000. Then C different targets. Each target is described by three integers, 0 <= T < m, 0 <= L <= R <= 100.

Output

For each case, first output the number of photos Aya can take, -1 if it's impossible to satisfy her needing. If there is a best strategy, output the number of photos of each girl Aya should take at each day on separate lines. The output must be in the same order as the input. If there are more than one best strategy, any one will be OK.

Output a blank line after each case.

题目大意:文文要要给幻想乡中的少女拍照。一共有n天,m个少女,在这n天中文文至少要给少女i(i<m)拍Gi张照片。在第t(t<n)中,只能拍Dt张照片,只能给特定的Ct个人拍照,而且每个人至少拍L张,但是少女只给文文拍R张。问文文能否完成任务,在完成任务的情况下最多能拍多少张照片。

思路:预备知识,无源无汇的上下界可行流,见SGU 194 Reactor Cooling(无源无汇上下界可行流)

然后来建图:引入源点S汇点T,n天一天一点,m个少女每人一点。S到每一天连一条边,上界为Dt,下界为0。每个少女到汇点连一条边,上界为无穷大,下界为Gi。对每一天,连一条边到所有要拍照的少女,下界为L,上界为R。然后引入超级源点SS,超级汇点TT,像无源无汇上下界可行流那样建边,然后T到S连一条边,容量为无穷大。最后从源点S到汇点T跑一遍最大流就是答案,每条边容量的取法和无源无汇上下界可行流一样。

小证明:原图为什么是那样建的我就不解释了。

至于加入超级源点和超级汇点之后为什么要连一条边T→S呢,因为根据无源无汇上下界可行流的做法,原图无源无汇,是应该有一个环的,而现在没有……

之后再从S到T跑一遍,会不会影响之前的流量下界呢?满足下界是来自于点与超级源点和超级汇点之间的边,如果我们把这两个点删掉,边的容量就没法变了,也就不会影响到流量下界。而我没有删掉,是因为若求出可行解之后,超级源点和超级汇点关联的边都应该是满流量的,再跑最大流不可能经过这两个点。

那么跑可行流的时候,和跑最大流的时候,流量是分开算的,那为什么不用加上原来可行流的流量呢?因为原先我们连了一条边T→S,根据无源无汇图中,每个点的入流等于出流,跑可行流的流量已经存在了T→S这条边中,跑最大流就时候,T→S的反向边就有了可行流的容量。所以跑最大流的时候会加上可行流的容量,就不用再加一遍了。

PS:之前以为输出每天的拍照数,后面跑样例的时候发现输出不对……然后把输出改成每天每人,忘了改数组大小RE了一遍>_<

代码(190MS):

 #include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std; const int MAXN = ;
const int MAXE = ;
const int INF = 0x3fff3fff; struct SAP {
int head[MAXN], gap[MAXN], dis[MAXN], pre[MAXN], cur[MAXN];
int to[MAXE], next[MAXE], flow[MAXE], cap[MAXE];
int n, ecnt, st, ed; void init() {
memset(head, , sizeof(head));
ecnt = ;
} void add_edge(int u, int v, int c) {
to[ecnt] = v; cap[ecnt] = c; flow[ecnt] = ; next[ecnt] = head[u]; head[u] = ecnt++;
to[ecnt] = u; cap[ecnt] = ; flow[ecnt] = ; next[ecnt] = head[v]; head[v] = ecnt++;
//printf("%d->%d %d\n", u, v, c);
} void bfs() {
memset(dis, 0x3f, sizeof(dis));
queue<int> que; que.push(ed);
dis[ed] = ;
while(!que.empty()) {
int u = que.front(); que.pop();
++gap[dis[u]];
for(int p = head[u]; p; p = next[p]) {
int &v = to[p];
if(cap[p ^ ] > flow[p ^ ] && dis[v] > n) {
dis[v] = dis[u] + ;
que.push(v);
}
}
}
} int Max_flow(int ss, int tt, int nn) {
st = ss, ed = tt, n = nn;
int ans = , minFlow = INF, u;
for(int i = ; i <= n; ++i) {
cur[i] = head[i];
gap[i] = ;
}
u = pre[st] = st;
bfs();
while(dis[st] < n) {
bool flag = false;
for(int &p = cur[u]; p; p = next[p]) {
int &v = to[p];
if(cap[p] > flow[p] && dis[u] == dis[v] + ) {
flag = true;
minFlow = min(minFlow, cap[p] - flow[p]);
pre[v] = u;
u = v;
if(u == ed) {
ans += minFlow;
while(u != st) {
u = pre[u];
flow[cur[u]] += minFlow;
flow[cur[u] ^ ] -= minFlow;
}
minFlow = INF;
}
break;
}
}
if(flag) continue;
int minDis = n - ;
for(int p = head[u]; p; p = next[p]) { int &v = to[p];
if(cap[p] > flow[p] && dis[v] < minDis) {
minDis = dis[v];
cur[u] = p;
}
}
if(--gap[dis[u]] == ) break;
++gap[dis[u] = minDis + ];
u = pre[u];
}
return ans;
}
} G; int n, m, c, d, l, r, x;
int f[MAXN], down[MAXE], id[MAXE]; int main() {
while(scanf("%d%d", &n, &m) != EOF) {
G.init();
memset(f, , sizeof(f));
int s = n + m + , t = s + ;
int ss = t + , tt = ss + ;
for(int i = ; i <= m; ++i) {
scanf("%d", &x);
f[i] -= x;
f[t] += x;
G.add_edge(i, t, INF);
}
int cnt = ;
for(int i = ; i <= n; ++i) {
scanf("%d%d", &c, &d);
G.add_edge(s, i + m, d);
while(c--) {
scanf("%d%d%d", &x, &l, &r);
f[i + m] -= l;
f[x + ] += l;
down[++cnt] = l; id[cnt] = G.ecnt;
G.add_edge(i + m, x + , r - l);
}
}
int sum = ;
for(int i = ; i <= t; ++i) {
if(f[i] > ) sum += f[i], G.add_edge(ss, i, f[i]);
else G.add_edge(i, tt, -f[i]);
}
G.add_edge(t, s, INF);
if(sum != G.Max_flow(ss, tt, tt)) puts("-1");
else {
printf("%d\n", G.Max_flow(s, t, tt));
for(int i = ; i <= cnt; ++i) printf("%d\n", down[i] + G.flow[id[i]]);
}
puts("");
}
}

ZOJ 3229 Shoot the Bullet(有源汇的上下界最大流)的更多相关文章

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

    有源汇带上下界最大流 在原图基础上连一条汇点到源点流量为inf的边,将有源汇网络流转化为无源汇网络流用相同方法判断是否满流,如果满流再跑一边源点到汇点的最大流就是答案 例题:Shoot the Bul ...

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

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

  3. ZOJ 3229 Shoot the Bullet(有源汇上下界最大流)

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=3442 题目大意: 一个屌丝给m个女神拍照,计划拍照n天,每一天屌丝给 ...

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

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

  5. ZOJ 3229 Shoot the Bullet | 有源汇可行流

    题目: 射命丸文要给幻想乡的居民照相,共照n天m个人,每天射命丸文照相数不多于d个,且一个人n天一共被拍的照片不能少于g个,且每天可照的人有限制,且这些人今天照的相片必须在[l,r]以内,求是否有可行 ...

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. js常用共同方法

    var uh_rdsp = (function(){ //获取根目录 var getContextPath = function(){ var pathName = document.location ...

  2. 【C++ Primer】读书笔记_第一章

    Main(): 1. C++程序必须包含main()函数,操作系统通过调用main来运行C++程序. 2. main()的形参可以为空. 3. main函数的返回类型必须为int,返回给操作系统.in ...

  3. optimize table 删除空洞--MYSQL

    来看看手册中关于 OPTIMIZE 的描述: OPTIMIZE [LOCAL | NO_WRITE_TO_BINLOG] TABLE tbl_name [, tbl_name] ... 如果您已经删除 ...

  4. java读取xml文件的四种方法

    Xml代码 <?xml version="1.0" encoding="GB2312"?> <RESULT> <VALUE> ...

  5. python 基于Anaconda import numpy 报错 Importing the multiarray numpy extension module failed.

    在windows中安装了 Anaconda 运行时报错 原因是系统环境变量起初并没有引入 E:\Tools\Anaconda\Library\bin 解决办法: 在系统环境变量中加入    E:\To ...

  6. Product Helper

    using System; using Microsoft.Xrm.Sdk; using Microsoft.Crm.Sdk.Messages; /// <summary> /// 产品 ...

  7. Hive(6)-DML数据操作

    一. 数据导入 1. 语法 load data [local] inpath 'path' [overwrite] into table table_name [partition (partcol1 ...

  8. Python学习 :json、pickle&shelve 模块

    数据交换格式 json 模块 json (JavaScript Object Notation)是一种轻量级的数据交换语言,以文字为基础,且易于让人阅读.尽管 json 是JavaScript的一个子 ...

  9. poj2676 (dfs+回溯)

    Sudoku Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 24108   Accepted: 11259   Specia ...

  10. 成都Uber优步司机奖励政策(1月16日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...