题目大概说在n天里给m个女孩拍照,每个女孩至少要拍Gi张照片,每一天最多拍Dk张相片且都有Ck个拍照目标,每一个目标拍照的张数要在[LkiRki]范围内,问最多能拍几张照片。

源点-天-女孩-汇点,这样子建容量网络。然后就是求这个有源汇流量有上下界容量网络的最大流:

  • 首先计算其可行流,POJ2396
  • 然后删除附加源、附加汇以及汇点到源点容量INF的边
  • 最后从源点到汇点跑一边最大流即可
 #include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
#define INF (1<<30)
#define MAXN 2222
#define MAXM 444*2222 struct Edge{
int v,cap,flow,next;
}edge[MAXM];
int vs,vt,NE,NV;
int head[MAXN]; void addEdge(int u,int v,int cap){
edge[NE].v=v; edge[NE].cap=cap; edge[NE].flow=;
edge[NE].next=head[u]; head[u]=NE++;
edge[NE].v=u; edge[NE].cap=; edge[NE].flow=;
edge[NE].next=head[v]; head[v]=NE++;
} int level[MAXN];
int gap[MAXN];
void bfs(){
memset(level,-,sizeof(level));
memset(gap,,sizeof(gap));
level[vt]=;
gap[level[vt]]++;
queue<int> que;
que.push(vt);
while(!que.empty()){
int u=que.front(); que.pop();
for(int i=head[u]; i!=-; i=edge[i].next){
int v=edge[i].v;
if(level[v]!=-) continue;
level[v]=level[u]+;
gap[level[v]]++;
que.push(v);
}
}
} int pre[MAXN];
int cur[MAXN];
int ISAP(){
bfs();
memset(pre,-,sizeof(pre));
memcpy(cur,head,sizeof(head));
int u=pre[vs]=vs,flow=,aug=INF;
gap[]=NV;
while(level[vs]<NV){
bool flag=false;
for(int &i=cur[u]; i!=-; i=edge[i].next){
int v=edge[i].v;
if(edge[i].cap!=edge[i].flow && level[u]==level[v]+){
flag=true;
pre[v]=u;
u=v;
//aug=(aug==-1?edge[i].cap:min(aug,edge[i].cap));
aug=min(aug,edge[i].cap-edge[i].flow);
if(v==vt){
flow+=aug;
for(u=pre[v]; v!=vs; v=u,u=pre[u]){
edge[cur[u]].flow+=aug;
edge[cur[u]^].flow-=aug;
}
//aug=-1;
aug=INF;
}
break;
}
}
if(flag) continue;
int minlevel=NV;
for(int i=head[u]; i!=-; i=edge[i].next){
int v=edge[i].v;
if(edge[i].cap!=edge[i].flow && level[v]<minlevel){
minlevel=level[v];
cur[u]=i;
}
}
if(--gap[level[u]]==) break;
level[u]=minlevel+;
gap[level[u]]++;
u=pre[u];
}
return flow;
}
int d[MAXN],low[][];
int main(){
int n,m,a,b,c,l,r;
while(~scanf("%d%d",&n,&m)){
memset(d,,sizeof(d));
int S=,T=n+m+;
vs=T+; vt=vs+; NV=vt+; NE=;
memset(head,-,sizeof(head));
for(int i=; i<=m; ++i){
scanf("%d",&a);
addEdge(i+n,T,INF);
d[T]-=a;
d[i+n]+=a;
}
memset(low,,sizeof(low));
vector<int> target[];
for(int i=; i<=n; ++i){
scanf("%d%d",&c,&a);
addEdge(S,i,a);
while(c--){
scanf("%d%d%d",&a,&l,&r);
++a;
target[i].push_back(a); low[i][a]=l;
addEdge(i,a+n,r-l);
d[a+n]-=l;
d[i]+=l;
}
}
int tag=NE;
addEdge(T,S,INF);
int tot=;
for(int i=S; i<=T; ++i){
if(d[i]<) addEdge(vs,i,-d[i]);
else addEdge(i,vt,d[i]),tot+=d[i];
}
tagEnd:
if(ISAP()!=tot){
puts("-1\n");
continue;
}
for(int i=tag; i<NE; ++i){
edge[i].cap=edge[i].flow=;
}
vs=S; vt=T;
ISAP();
tot=;
for(int i=head[vs]; i!=-; i=edge[i].next){
if(i&) continue;
tot+=edge[i].flow;
}
printf("%d\n",tot);
for(int u=; u<=n; ++u){
for(int i=head[u]; i!=-; i=edge[i].next){
int v=edge[i].v-n;
if(i& || v< || v>m) continue;
low[u][v]+=edge[i].flow;
}
}
for(int u=; u<=n; ++u){
for(int i=; i!=target[u].size(); ++i){
printf("%d\n",low[u][target[u][i]]);
}
}
putchar('\n');
}
return ;
}

ZOJ3229 Shoot the Bullet(有源汇流量有上下界网络的最大流)的更多相关文章

  1. HDU3157 Crazy Circuits(有源汇流量有上下界网络的最小流)

    题目大概给一个电路,电路上有n+2个结点,其中有两个分别是电源和负载,结点们由m个单向的部件相连,每个部件都有最少需要的电流,求使整个电路运转需要的最少电流. 容量网络的构建很容易,建好后就是一个有源 ...

  2. POJ2396 Budget(有源汇流量有上下界网络的可行流)

    题目大概给一个有n×m个单元的矩阵,各单元是一个非负整数,已知其每行每列所有单元的和,还有几个约束条件描述一些单元是大于小于还是等于某个数,问矩阵可以是怎样的. 经典的流量有上下界网络流问题. 把行. ...

  3. ZOJ2314 Reactor Cooling(无源汇流量有上下界网络的可行流)

    题目大概说一个核反应堆的冷却系统有n个结点,有m条单向的管子连接它们,管子内流量有上下界的要求,问能否使液体在整个系统中循环流动. 本质上就是求一个无源汇流量有上下界的容量网络的可行流,因为无源汇的容 ...

  4. zoj3229 Shoot the Bullet (有源汇最大流)

    题目大意:文文要给幻想乡的女♂孩子们拍照,一共n天,m个女♂孩子,每天文文至多拍D[i]张照片,每个女♂孩子总共要被文文至少拍G[i]次.在第i天,文文可以拍c[i]个女♂孩子,c[i]个女♂孩子中每 ...

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. [Java 基础] 并发队列ConcurrentLinkedQueue和阻塞队列LinkedBlockingQueue用法

    reference : http://www.cnblogs.com/linjiqin/archive/2013/05/30/3108188.html 在Java多线程应用中,队列的使用率很高,多数生 ...

  2. 不同版本CUDA编程的问题

    1 无法装上CUDA的toolkit 卸载所有的NVIDIA相关的app,包括NVIDIA的显卡驱动,然后重装. 2之前的文件打不开,one or more projects in the solut ...

  3. Google140道面试题

    FQ找来,可能历史比较悠久了,慢慢看. 原文连接:http://www.impactinterview.com/2009/10/140-google-interview-questions/ Goog ...

  4. NPOI 1.2.4教程 –日期函数

    //Excel中有非常丰富的日期处理函数,在NPOI中同样得到了很好的支持.如下图: using NPOI.HSSF.UserModel; using NPOI.HPSF; using NPOI.PO ...

  5. ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(一) 之 基层数据搭建,让数据活起来(数据获取)

    大家好,本篇是接上一篇 ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(零) 前言  ASP.NET SignalR WebIM系列第二篇.本篇会带领大家将 LayIM ...

  6. 《Thinking in Java》十七章_容器深入研究_练习14(Page486)

    练习14 Properties的继承树如下:

  7. HTML5学习之WebWork多线程处理(八)

    多线程技术在服务端技术中已经发展的很成熟了,而在Web端的应用中却一直是鸡肋 在新的标准中,提供的新的WebWork API,让前端的异步工作变得异常简单. 使用:创建一个Worker对象,指向一个j ...

  8. 简简单单的一个PYTHON多进程实现

    因为在作自动化部署时,希望能将多个服务分不同的批次进行发布, 同一批次的机器同时发布, 如果前面一批次出错误,后面就需要停止整 个流程. 那可以简单的用threading来实现了. thread_li ...

  9. c程序辨别系统是64位 or 32位

    #include <stdio.h> int main(void) { int i = 0x80000000; ){ printf("i = %d\n", i); pr ...

  10. HP SAN Switch光纖交換機命令行畫zone

    有時候我們無法登陸網頁交互界面去操縱交換機,如下提供了命令行方式從交換機劃zone 1.創建別名 alicreate "SummaryDB_N", "211,14; 21 ...