ZOJ3229:Shoot the Bullet——题解
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3229
题目大意:射命丸文要给幻想乡的居民照相,共照n天m个人,每天射命丸文照相数不多于d个,且一个人n天一共被拍的照片不能少于g个,且每天可照的人有限制,且这些人今天照的相片必须在[l,r]以内,求是否有可行解,如果有则输出最多照片数,并且输出每天每个可以被照的人的被照的照片数。
————————————————————————
https://www.cnblogs.com/kane0526/archive/2013/04/05/3001108.html
按照这篇博客的顺序先刷了这道题。
(话说射命丸文怎么就成屌丝了……)
建图很显然,源点到每天连一条[0,d],每天到每天能连的人建[l,r],每个人到汇点连[g,INF]。
现在就是有源汇上下界网络流的题了。
按照无源汇上下界网络流的想法(可参考我的上一篇博客ZOJ2314)是很容易建的,有源汇的话我们就手动把它变成无源汇的即可。
那么我们从汇点向源点连一条[0,INF]不就可以了吗?
接下来就是我们建立一个超级源汇点,跑一遍无源汇上下界网络流即可。
但!是!还!没!完!我们跑完的流量实际上只是流向超级汇点的流量,它只是流向汇点的流量的一部分,在残余网络里还可能存在一些被卡在管子里的流量无法流向超级汇点但可以流向汇点。
所以我们机智的删掉了超级源汇点,再跑一遍从源点到汇点的最大流即可。
至于每个人每天的照片,那自然是每天到每个人的反边的容量+下界了!
!注意!18.1.6更新,修正了代码的问题和表述的问题:我们实际上对于卡在管子里的流不仅仅是原图,还有些我们做上下界网络流的边,所以这些边我们不能删。也就是说,总流量就等于我们删除超级源汇点之后的最大流,因为我们把流向超级汇点的流量也一并流向了汇点。
#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=;
const int M=;
const int INF=1e9;
inline int read(){
int X=,w=;char ch=;
while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
while(isdigit(ch))X=(X<<)+(X<<)+(ch^),ch=getchar();
return w?-X:X;
}
struct node{
int nxt;
int to;
int w;
}edge[M];
int head[N],du[N],id[][],low[][],cnt=-;
int S,T;
void add(int u,int v,int w){
cnt++;
edge[cnt].to=v;
edge[cnt].w=w;
edge[cnt].nxt=head[u];
head[u]=cnt;
}
int lev[N],cur[N],dui[N];
bool bfs(int m){
int r=;
for(int i=;i<=m;i++){
lev[i]=-;
cur[i]=head[i];
}
dui[]=S,lev[S]=;
int u,v;
for(int l=;l<=r;l++){
u=dui[l];
for(int e=head[u];e!=-;e=edge[e].nxt){
v=edge[e].to;
if(edge[e].w>&&lev[v]==-){
lev[v]=lev[u]+;
r++;
dui[r]=v;
if(v==T)return ;
}
}
}
return ;
}
int dinic(int u,int flow,int m){
if(u==m)return flow;
int res=,delta;
for(int &e=cur[u];e!=-;e=edge[e].nxt){
int v=edge[e].to;
if(edge[e].w>&&lev[u]<lev[v]){
delta=dinic(v,min(edge[e].w,flow-res),m);
if(delta>){
edge[e].w-=delta;
edge[e^].w+=delta;
res+=delta;
if(res==flow)break;
}
}
}
if(res!=flow)lev[u]=-;
return res;
}
inline void init(){
memset(head,-,sizeof(head));
memset(du,,sizeof(du));
memset(id,,sizeof(id));
cnt=-;
return;
}
int main(){
int n,m;
while(scanf("%d%d",&n,&m)!=EOF&&n){
int st=m+n+,ed=m+n+;
init();
for(int i=;i<=m;i++){
int g=read();
add(i,ed,INF-g);
add(ed,i,);
du[i]-=g;
du[ed]+=g;
}
for(int i=m+;i<=m+n;i++){
int c=read(),d=read();
add(st,i,d);
add(i,st,);
for(int j=;j<=c;j++){
int t=read()+,l=read(),r=read();
add(i,t,r-l);
add(t,i,);
du[i]-=l;
du[t]+=l;
id[i-m][t]=cnt;
low[i-m][t]=l;
}
}
add(ed,st,INF);add(st,ed,);
S=ed+;T=S+;
int ans=,full=;
for(int i=;i<=m+n+;i++){
if(du[i]>){
add(S,i,du[i]);
add(i,S,);
full+=du[i];
}else if(du[i]<){
add(i,T,-du[i]);
add(T,i,);
}
}
while(bfs(T)==)ans+=dinic(S,INF,T);
if(ans!=full)puts("-1");
else{
head[S]=head[T]=-;
S=st;T=ed;ans=;
while(bfs(ed)==)ans+=dinic(S,INF,T);
printf("%d\n",ans);
for(int i=;i<=n;i++){
for(int j=;j<=m;j++){
if(id[i][j]){
printf("%d\n",edge[id[i][j]].w+low[i][j]);
}
}
}
}
puts("");
}
return ;
}
ZOJ3229:Shoot the Bullet——题解的更多相关文章
- zoj3229 Shoot the Bullet (有源汇最大流)
题目大意:文文要给幻想乡的女♂孩子们拍照,一共n天,m个女♂孩子,每天文文至多拍D[i]张照片,每个女♂孩子总共要被文文至少拍G[i]次.在第i天,文文可以拍c[i]个女♂孩子,c[i]个女♂孩子中每 ...
- ZOJ3229 Shoot the Bullet(有源汇流量有上下界网络的最大流)
题目大概说在n天里给m个女孩拍照,每个女孩至少要拍Gi张照片,每一天最多拍Dk张相片且都有Ck个拍照目标,每一个目标拍照的张数要在[Lki, Rki]范围内,问最多能拍几张照片. 源点-天-女孩-汇点 ...
- 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,如果有解求屌 ...
- ZOJ3229 Shoot the Bullet
http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=20756 思路:就讲一下有源汇上下界最大流的做法吧!对于所有的边,就按照无源汇 ...
- ZOJ3229 Shoot the Bullet [未AC]
Time Limit: 2 Seconds Memory Limit: 32768 KB Special Judge Gensokyo is a world which exist ...
- P5192 Zoj3229 Shoot the Bullet|东方文花帖|【模板】有源汇上下界最大流
我们要做这道题首先先来学习: 无源汇上下界可行流 什么是无源汇上下界可行流 在一张图中,没有s和t,每条边有流量下界和流量上界,流量在这个区间内,求是否存在一种方案在满足流量平衡的情况下,使所有边满足 ...
- zoj 3229 Shoot the Bullet(无源汇上下界最大流)
题目:Shoot the Bullet 收藏:http://www.tuicool.com/articles/QRr2Qb 把每一天看成一个点,每个女孩也看成一个点,增加源和汇s.t,源向每一天连上[ ...
- ZOJ 3229 Shoot the Bullet [上下界最大流]
ZOJ 3229 Shoot the Bullet 题意:此生无悔入东方 上下界最大流 spj挂掉了我也不知道对不对,把代码放这里吧以后正常了可能会评测一下 #include <iostream ...
随机推荐
- 如何实现最佳的跨平台游戏体验?Unity成亮解密实时渲染
7月31日,2018云创大会游戏论坛在杭州国际博览中心103B圆满举行.本场游戏论坛聚焦探讨了可能对游戏行业发展有重大推动的新技术.新实践,如AR.区块链.安全.大数据等. Unity大中华区技术经理 ...
- 聊聊WS-Federation
本文来自网易云社区 单点登录(Single Sign On),简称为 SSO,目前已经被大家所熟知.简单的说, 就是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统. 举例: 我们 ...
- C 基本运算
一 算术运算 C语言一共有34种运算符 包括了常见的加减乘除运算 1. 加法运算+ 除开能做加法运算 还能表示正号: +5, +90 2. 减法运算- 除开能做减法运算 还能表示符号: -10, -2 ...
- python函数参数默认值及重要警告
最有用的形式是对一个或多个参数指定一个默认值.这样创建的函数,可以用比定义时允许的更少的参数调用,比如: def ask_ok(prompt, retries=4, reminder='Please ...
- 反片语 (Ananagrams,UVa 156)
题目描述: #include <iostream> #include <string> #include <cctype> #include <vector& ...
- python基本数据类型——元组
元组 元组是一种不可变的序列,创建后不可以修改元素值 # 创建只包含一个元素的元组 >>a = (3,) >>print(a) (3,) #使用 tuple() 转换为元组 & ...
- [递推+矩阵快速幂]Codeforces 1117D - Magic Gems
传送门:Educational Codeforces Round 60 – D 题意: 给定N,M(n <1e18,m <= 100) 一个magic gem可以分裂成M个普通的gem ...
- iostat lsof
转至:http://www.51testing.com/html/48/202848-242043.html 命令总结: 1. top/vmstat 发现 wa%过高,vmstat b >1: ...
- Python练习—循环
1.输入n的值,求出n的阶乘. s=1 n = int(input("请输入一个数")) for i in range(1,n+1): s=s*i print(s) 2.折纸上月球 ...
- .mat转成.npy文件+Python(Pytorch)压缩裁剪图片
需求:现有数据文件V1.mat,里面包含多个数据集,现需将里面的images数据集提取出来,然后进行压缩裁剪成指定大小 V1.mat数据集目录: 1.从mat文件中提取数据(使用Python) V1. ...