题目

题目描述
有些邪恶富人们喜欢玩生死游戏。简单的说就是找一些穷人,让他们进行相互厮杀。富人们则在旁观看并下注。
今天的游戏跟以往有些不同。参与游戏的穷人排成了一个n*m的矩阵,你的任务是组织游戏并决定这些人的生死。
如果第i行,第j列的人幸存了下来,你将获得Wij块钱,否则你将得到Bij块钱。
同时,富人们会提出一些奇怪的要求。他们每个人都会指定一个子矩阵,然后说:如果这个子矩阵的所有穷人都死了(或者都幸存下来了),你将得到S块钱。
你并不关心这些穷人的生死,你只希望你得到的钱尽可能多。
请注意,这里对杀人没有限制,你可以杀掉所有人,也可以一个也不杀。
输入
第一行,三个空格间隔的整数n,m,r ,分别表示矩阵的行数、列数和富人们提出的要求的数量。
接下来是n*m个整数,表示矩阵B。
接下来是n*m个整数,表示矩阵W。(0<=Bij,Wij<=100)
接下来r行,每行描述一个要求:
每个要求有6个空格间隔的整数构成:R1,C1,R2,C2,T,S。它表示一个子矩阵的左上角(R1,C1)和右下角(R2,C2)的坐标。T=1表示矩阵中的所有人必须死,T=0表示矩阵中所有人都必须活下来。S表示如果你满足了这个要求,你将得到的钱数。(0<=S<=10000)请注意,这里对杀人没有限制,你可以杀掉所有人,也可以一个也不杀。
输出
一行,一个整数,表示所求答案。
样例1
输入
2 2 3
34 44
63 30
1 9
53 57
1 2 2 2 1 2843
1 1 2 1 0 2169
2 1 2 1 1 6980

输出
9994

样例2
输入
2 2 3
50 93
65 70
52 28
91 25
1 1 2 1 0 9862
2 1 2 1 1 1876
2 2 2 2 0 4190

输出
14313

提示
对于30%的数据 1<=n,m<=10 0<=r=1000

对于50%的数据 1<=n,m<=30 0<=r<=10000

对于100%的数据 1<=n,m<=50 0<=r<=50000

分析

这道题的选择之间有关系,很容易想到最小割。

ans=∑i=1n∑j=1mbij+wij−∑i,ji,j这个人死了wi,j−∑i,ji,j这个人活着bi,j−∑i没有满足第i个条件si

我们从S到每个点连容量为bi的边,从每个点到T连容量为wi的边,当点在S时,就代表这个人死了,在T则活着。
然后考虑富人的要求,对于每个要求我们新增一个点。
对于第i个要求:

  • 如果要求所有人都活着,那么当这个点在S时,就会付出si的代价。就从这个点到T连一条容量为si的边,再从矩阵内所有的点向这个点连一条容量为+∞的边。
  • 如果要求所有人都死,那么当这个点在T时,就会付出si的代价。就从S到这个点连一条容量为si的边,再从这个点到矩阵内所有的点连一条容量为+∞的边。

    显然边十分多,但是连接的点往往是在一个二维区间内的所有点,可以效仿A+B Problem,用二维线段树优化这道题。

这道题,其实就是(A+B)2Problem。

代码

#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
#define MAXN 50
#define MAXR 50000
#define INF 0x7fffffff
using namespace std;
queue<int>q;
struct node{int v,cap;node *back,*next;
}*adj[MAXN*MAXN*20+MAXR+10],edge[10000000+10],*ecnt=edge;
int root[MAXN*4+10],ls[MAXN*MAXN*4*4+10],rs[MAXN*MAXN*4*4+10],tot,m,S,T,n,r,ans,c,dist[MAXN*MAXN*20+MAXR+10],vd[MAXN*MAXN*20+MAXR+10],flow,id[MAXN*MAXN*4*4+10][2],tcnt;
void addedge(int u,int v,int cap){node *p=++ecnt;p->v=v;p->cap=cap;p->next=adj[u];adj[u]=p;p=p->back=++ecnt;p->v=u;p->cap=0;p->next=adj[v];adj[v]=p;p->back=ecnt-1;
}
void build2(int &i,int l,int r,int ll,int rr){i=++tcnt;id[i][0]=++tot,id[i][1]=++tot;if(l==r){for(int j=ll;j<=rr;j++){addedge(id[i][1],(j-1)*m+l,INF);addedge((j-1)*m+l,id[i][0],INF);}return;}int mid=(l+r)>>1;build2(ls[i],l,mid,ll,rr);build2(rs[i],mid+1,r,ll,rr);addedge(id[i][1],id[ls[i]][1],INF);addedge(id[i][1],id[rs[i]][1],INF);addedge(id[ls[i]][0],id[i][0],INF);addedge(id[rs[i]][0],id[i][0],INF);
}
void build1(int i,int l,int r){build2(root[i],1,m,l,r);if(l==r)return;int mid=(l+r)>>1;build1(i<<1,l,mid);build1((i<<1)|1,mid+1,r);
}
void link2(int i,int l,int r,int ll,int rr,bool f,int c){if(ll<=l&&rr>=r){if(f)addedge(tot,id[i][1],c);else addedge(id[i][0],tot,c);return;}if(l>rr||r<ll)return;int mid=(l+r)>>1;link2(ls[i],l,mid,ll,rr,f,c);link2(rs[i],mid+1,r,ll,rr,f,c);
}
void link1(int i,int l,int r,int ll,int rr,int wl,int wr,bool f,int c){if(ll<=l&&rr>=r){link2(root[i],1,m,wl,wr,f,c);return;}if(l>rr||r<ll)return;int mid=(l+r)>>1;link1(i<<1,l,mid,ll,rr,wl,wr,f,c);link1((i<<1)|1,mid+1,r,ll,rr,wl,wr,f,c);
}
void Read(int &x){char c;while(c=getchar(),c!=EOF)if(c>='0'&&c<='9'){x=c-'0';while(c=getchar(),c>='0'&&c<='9')x=x*10+c-'0';ungetc(c,stdin);return;}
}
void read(){Read(n),Read(m),Read(r);int i,j,b,w;S=n*m+1,tot=T=S+1;build1(1,1,n);for(i=1;i<=n;i++)for(j=1;j<=m;j++){Read(b);addedge(S,(i-1)*m+j,b);ans+=b;}for(i=1;i<=n;i++)for(j=1;j<=m;j++){Read(w);addedge((i-1)*m+j,T,w);ans+=w;}int h1,h2,s1,s2,t,s;for(i=1;i<=r;i++){Read(h1),Read(s1),Read(h2),Read(s2),Read(t),Read(s);ans+=s;if(t){addedge(S,++tot,s);link1(1,1,n,h1,h2,s1,s2,1,s);}else{addedge(++tot,T,s);link1(1,1,n,h1,h2,s1,s2,0,s);}}
}
void bfs(){q.push(T);int u;while(!q.empty()){u=q.front();q.pop();for(node *p=adj[u];p;p=p->next){if(p->back->cap&&!dist[p->v]){dist[p->v]=dist[u]+1;q.push(p->v);}}}dist[T]=0;
}
int dfs(int u,int augu){if(u==T)return augu;int augv=0,v,delta,mind=tot-1;for(node *p=adj[u];p;p=p->next)if(p->cap){v=p->v;if(dist[u]==dist[v]+1){delta=min(augu-augv,p->cap);delta=dfs(v,delta);augv+=delta;p->cap-=delta;p->back->cap+=delta;if(augu==augv||dist[S]>=tot)return augv;}mind=min(dist[v],mind);}if(!augv){if(!--vd[dist[u]])dist[S]=tot;vd[dist[u]=mind+1]++;}return augv;
}
void sap(){bfs();for(int i=1;i<=tot;i++){if(!dist[i]){dist[i]=tot;continue;}vd[dist[i]]++;}dist[T]=0,vd[0]++;while(dist[S]<tot)flow+=dfs(S,INF);
}
int main()
{read();sap();printf("%d\n",ans-flow);
}

转载于:https://www.cnblogs.com/outerform/p/5921848.html

【网络流+线段树】[CQBZOJ3065]生死游戏((A+B)^2 Problem)相关推荐

  1. 【BZOJ-3681】Arietta 网络流 + 线段树合并

    3681: Arietta Time Limit: 20 Sec  Memory Limit: 64 MB Submit: 182  Solved: 70 [Submit][Status][Discu ...

  2. Codeforces 1045. A. Last chance(网络流 + 线段树优化建边)

    题意 给你 \(n\) 个武器,\(m\) 个敌人,问你最多消灭多少个敌人,并输出方案. 总共有三种武器. SQL 火箭 - 能消灭给你集合中的一个敌人 \(\sum |S| \le 100000\) ...

  3. 线段树开新坑:kuangbin带你飞

    写在最前面的废话 这里I以前的题是暑假刚刚开始的时候在家写的,然后多校一波就荒废了 9月开头回家一波,重新填坑,= =,kuangbin带你飞的pdf,这才一半题,后面还有一波,蓝瘦,慢慢写吧,不写题 ...

  4. Codeforces Round #740 (Div. 2) F. Top-Notch Insertions 线段树 / 平衡树 + 组合数学

    传送门 文章目录 题意: 思路: 题意: 思路: 考虑最终的序列是什么鸭子的,首先序列肯定单调不降,也就是a1≤a2≤a3≤...≤ana_1\le a_2\le a_3\le ...\le a_na ...

  5. POJ2886线段树 Joseph游戏(单点更新)

    题目:Who Gets the Most Candies? 题意: 1.n个人进行Joseph游戏,游戏共p轮(p为 思路:用相对坐标来处理,例如这一轮出局的是p,下一个要+m,则p出局时p+1就变成 ...

  6. 【CF1045A】A Last chance【贪心】【线段树优化建图】【网络流构造方案】

    题意:有nnn个武器和mmm个飞船,武器有下面三种 从给定的集合SSS中击破一个. 在给定的区间[L,R][L,R][L,R]中击破一个. 对于给定的a,b,ca,b,ca,b,c,选择000个或22 ...

  7. 【李超树】李超线段树维护凸包(凸壳) (例题:blue mary开公司+线段游戏+ZZH的旅行)

    文章目录 前言 李超树 引入(斜率优化) 什么是李超树? 李超树活着能干点什么? 算法思想(使用手册?) 插入 查询 模板 判断是否覆盖(优不优) 插入 查询 例题 板题:BlueMary开公司 分析 ...

  8. CodeForces 1045A. Last chance(线段树+网络流SAP)

    网络流,对三种武器分别有不同建图的方法,核心宗旨是:源点->武器->飞船->汇点. SQL rockets – every SQL rocket can destroy at mos ...

  9. [BZOJ4372][烁烁的游戏][动态树分治+线段树+LCA]

    [BZOJ4372][烁烁的游戏][动态树分治+线段树+LCA] 题目大意: 给定一颗nn个节点的树,边权均为11,初始每个点权值为00 . 其中操作QQ xx询问x点的点权,操作 MM xx dd ...

  10. 【BZOJ4372】烁烁的游戏 动态树分治+线段树

    [BZOJ4372]烁烁的游戏 Description 背景:烁烁很喜欢爬树,这吓坏了树上的皮皮鼠. 题意: 给定一颗n个节点的树,边权均为1,初始树上没有皮皮鼠. 烁烁他每次会跳到一个节点u,把周围 ...

最新文章

  1. 数据结构与算法(2-1)线性表之顺序存储(顺序表)
  2. iOS的KVO实现剖析
  3. 彻底疯了,要给雷锋开博客?
  4. php调用restful接口_jzq_sdk_php
  5. HashMap的容量(桶的数量)为什么要是2的n次方
  6. JZOJ 5453. 【NOIP2017提高A组冲刺11.5】好路线
  7. 给 Android 开发人员的 RxJava 具体解释
  8. android 动态调用apk,通过反射动态加载未安装apk
  9. 第二届(2009年)中国信息技术应用学术研讨会征文延期通知
  10. UNIX/Linux系统管理技术手册(1)----脚本和shell
  11. matlab实现prim算法,Prim算法和Kruskal算法的Matlab实现
  12. 智能推荐系统之数据预处理
  13. 用C#写了一个新增用户就发送邮件和手机短信的SqlServer触发器(附源码)
  14. python给矩阵赋值_python 实现矩阵旋转
  15. 使用参数非参数和机器学习方法分析印度降雨变化,能给我国带来什么警示?
  16. SecureCRT配置自动保存日志(实用)
  17. springboot中.yml 用jasypt 密码加密
  18. PS快速切换证件照背景颜色
  19. 四六级得分技巧备考和心态
  20. 以下7种硬件测试的种类,不知道的赶紧收藏了!

热门文章

  1. 通过Windows组策略限制证书组织流氓软件的安装运行
  2. iOS开发之控制器之间传值
  3. 设置TOMCAT SESSIONID 字符长度和生成算法
  4. python 报错 wxPyDeprecationWarning: Using deprecated class PySimpleApp.
  5. Latex 资料汇总(持续更新)
  6. 开源C++项目Google JavaScript引擎V8挑战实录,带你进入V8之旅
  7. EMC NetWorker简单管理指南(二)
  8. 读凤凰网经典语句记录一
  9. JsSIP 注册,拨打填坑
  10. 调试Python的方式