博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BZOJ3577:玩手机(最大流,二维ST表)
阅读量:5846 次
发布时间:2019-06-18

本文共 3118 字,大约阅读时间需要 10 分钟。

Description

现在有一堆手机放在坐标网格里面(坐标从1开始),坐标(i,j)的格子有s_(i,j)个手机。

玩手机当然需要有信号,不过这里的手机与基站与我们不太一样。基站分为两种:发送站和接收站(以下简称为A站和B站)。每个手机必须同时与一个A站和一个B站通信才能工作。
每个基站有一个正方形的覆盖范围(平行于网格)。覆盖范围可以用左下角和右上角的坐标表示(范围包括边角)。显然,手机只有在某个基站的范围内才能与这个基站通信。除此之外,每个基站还有最大接入的手机数量限制。
求最大同时工作的手机数量。

Input

第一行四个整数R,C,a,b,表示坐标网格的规模是R×C,共有a个A站和b个B站。

接下来是一个R×C的矩阵,第i行第j列的数为s_(i,j)。
接下来a行,每行5个数w,x1,y1,x2,y2,表示第i个A站最大接入w个手机,覆盖范围为(x1,y1)~(x2,y2)。
接下来b行,每行5个数w,x1,y1,x2,y2,含义同上。

Output

一个整数,即最大同时工作的手机数量。

Sample Input

3 3 1 2
1 1 1
1 1 1
1 1 1
100 1 1 3 3
4 1 1 2 2
4 2 2 3 3

Sample Output

7

数据规模与约定
1≤R,C≤60,0≤a,b≤10,000,0≤s,w≤10,000,1≤x1≤x2≤R,1≤y1≤y2≤C。

Solution

朴素的网络流应该很简单,直接$r \times c$的每个格子拆点,左边连$a$基站右边连$b$基站,然后$a$基站连源点,$b$基站连汇点就好了。

但是这样的话会边数爆炸,所以可以用二维$ST$表优化连边。具体的可以看神仙的博客QwQ

Code

1 #include
2 #include
3 #include
4 #include
5 #define N (300009) 6 #define INF (0x7f7f7f7f) 7 using namespace std; 8 9 struct Edge{
int to,next,flow;}edge[N<<2]; 10 int r,c,a,b,w,x,y,u,v,id_num,val,s,t=300000; 11 int Depth[N],f[69][69][10],g[69][69][10],LOG2[69]; 12 int head[N],num_edge; 13 queue
q; 14 15 void add(int u,int v,int l) 16 { 17 edge[++num_edge]=(Edge){v,head[u],l}; head[u]=num_edge; 18 edge[++num_edge]=(Edge){u,head[v],0}; head[v]=num_edge; 19 } 20 21 int DFS(int x,int low,int t) 22 { 23 if (x==t || !low) return low; 24 int f=0; 25 for (int i=head[x]; i; i=edge[i].next) 26 if (Depth[edge[i].to]==Depth[x]+1) 27 { 28 int Min=DFS(edge[i].to,min(low,edge[i].flow),t); 29 edge[i].flow-=Min; 30 edge[((i-1)^1)+1].flow+=Min; 31 f+=Min; low-=Min; 32 if (!low) break; 33 } 34 if (!f) Depth[x]=-1; 35 return f; 36 } 37 38 bool BFS(int s,int t) 39 { 40 memset(Depth,0,sizeof(Depth)); 41 Depth[s]=1; 42 q.push(s); 43 while (!q.empty()) 44 { 45 int x=q.front(); q.pop(); 46 for (int i=head[x]; i; i=edge[i].next) 47 if (!Depth[edge[i].to] && edge[i].flow) 48 { 49 Depth[edge[i].to]=Depth[x]+1; 50 q.push(edge[i].to); 51 } 52 } 53 return Depth[t]; 54 } 55 56 int Dinic(int s,int t) 57 { 58 int ans=0; 59 while (BFS(s,t)) 60 ans+=DFS(s,INF,t); 61 return ans; 62 } 63 64 int main() 65 { 66 for (int i=2; i<=60; ++i) LOG2[i]=LOG2[i>>1]+1; 67 scanf("%d%d%d%d",&r,&c,&a,&b); 68 for (int i=1; i<=r; ++i) 69 for (int j=1; j<=c; ++j) 70 { 71 scanf("%d",&val); 72 f[i][j][0]=++id_num; g[i][j][0]=++id_num; 73 add(f[i][j][0],g[i][j][0],val); 74 } 75 for(int k=1; k<6; ++k) 76 for(int i=1; i<=r; ++i) 77 for(int j=1; j<=c; ++j) 78 if(i+(1<
<=r && j+(1<
<=c) 79 { 80 f[i][j][k]=++id_num; g[i][j][k]=++id_num; 81 add(f[i][j][k],f[i][j][k-1],INF); add(g[i][j][k-1],g[i][j][k],INF); 82 add(f[i][j][k],f[i+(1<

转载于:https://www.cnblogs.com/refun/p/10630229.html

你可能感兴趣的文章
评论:人才流失强力折射出现实畸形人才观
查看>>
ios的google解析XML框架GDataXML的配置及使用
查看>>
netty-当一个客户端连接到来的时候发生了什么
查看>>
在51CTO三年年+了,你也来晒晒
查看>>
js控制图片等比例缩放
查看>>
Openstack API常用命令
查看>>
关于k-means聚类算法的matlab实现
查看>>
跟随我在oracle学习php(8)
查看>>
UVA-10212 The Last Non-zero Digit. 分解质因子+容斥定理
查看>>
Kotlin的语法糖(一)基础篇
查看>>
亚信安全参加第六届全国等保技术大会 态势感知助力“等保2.0”落地
查看>>
大数据公司Palantir融得7亿美元 曾追踪拉登
查看>>
建立备份策略的重要性
查看>>
发力IoT领域 Marvell注重生态系统发展
查看>>
你应该知道的 RPC 原理
查看>>
Ubuntu安装词典
查看>>
Spring解析
查看>>
python中str和repr区别
查看>>
数据挖掘-同比与环比
查看>>
RedHat6 管理应用服务【11】
查看>>