当前位置: 首页 > news >正文

bzoj3894: 文理分科

题意:给一个n*m的网格图,每个点被染黑有一个收益,染白有一个收益,如果这个点相邻(有公共边)的格子与它同色,又会有一个额外收益,求最大收益方案。

考虑类似最大闭合子图的思路,我们将总收益先算出来,然后跑最小割,最后用总收益减掉最小割即为答案。

怎么建图呢?我们要保证一个点选文科后,它周围选理科的点不能有理科额外收益,选理科也同理。

考虑这么建图:每个点拆成3个点,拆出来的第一个点向它周围的点连INF,同时该点本身向拆出来的第一个点连文科额外值,拆出来第二个点与第一个点相反,即被第一个点连到的点(相邻的点)向它连INF,然后被拆出来的第二个点向本体连理科额外值。每个点本体,S向其连文科加上文科额外值,其向T连理科加上理科额外值。

仔细思考,会发现这样能使:一旦周围中出了一个叛徒,被多算的额外值就会被扣除掉。

一开始也想到了最小割来做,但始终解决不了怎么去掉多余的额外值(因为想的是只拆一个点),再次%ihopenot。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define N 200005
 4 #define INF 1e9
 5 #define id(x,y) (((x)-1)*m+(y))
 6 inline int read(){
 7     int x=0,f=1; char a=getchar();
 8     while(a<'0' || a>'9') {if(a=='-') f=-1; a=getchar();}
 9     while(a>='0' && a<='9') x=x*10+a-'0',a=getchar();
10     return x*f;
11 }
12 const int dir[4][2]={1,0,-1,0,0,1,0,-1};
13 int S,T,P,n,m,cur[N],head[N],ans,cnt,d[N],si[105][105],ai[105][105],alls[105][105],alla[105][105];
14 bool vis[N];
15 queue<int>Q;
16 struct edges{
17     int to,cap,flow,next;
18 }e[2*N];
19 inline void insert(int u,int v,int c){
20     e[cnt]=(edges){v,c,0,head[u]};head[u]=cnt++;
21     e[cnt]=(edges){u,0,0,head[v]};head[v]=cnt++;
22 }
23 inline bool bfs(){
24     memset(vis,0,sizeof(vis));
25     d[S]=0; Q.push(S); vis[S]=1;
26     while(!Q.empty()){
27         int x=Q.front(); Q.pop();
28         for(int i=head[x];i>=0;i=e[i].next)
29             if(!vis[e[i].to] && e[i].cap>e[i].flow)
30                 d[e[i].to]=d[x]+1,vis[e[i].to]=1,Q.push(e[i].to);
31     }
32     return vis[T];
33 }
34 int dfs(int x,int a){
35     if(x==T || !a) return a;
36     int f,flow=0;
37     for(int& i=cur[x];i>=0;i=e[i].next){
38         if(d[e[i].to]==d[x]+1 && (f=dfs(e[i].to,min(a,e[i].cap-e[i].flow)))>0)
39         e[i].flow+=f,flow+=f,e[i^1].flow-=f,a-=f;
40         if(!a) break;
41     }
42     return flow;
43 }
44 inline int maxflow(){
45     int flow=0;
46     while(bfs()){
47         for(int i=S;i<=T;i++) cur[i]=head[i];
48         flow+=dfs(S,INF);
49     }
50     return flow;
51 }
52 int main(){
53     memset(head,-1,sizeof(head));
54     n=read(); m=read(); S=0; T=3*n*m+1; P=n*m;
55     for(int i=1;i<=n;i++)
56         for(int j=1;j<=m;j++)
57             ai[i][j]=read(),ans+=ai[i][j];
58     for(int i=1;i<=n;i++)
59         for(int j=1;j<=m;j++)
60             si[i][j]=read(),ans+=si[i][j];
61     for(int i=1;i<=n;i++)
62         for(int j=1;j<=m;j++)
63             alla[i][j]=read(),ans+=alla[i][j];
64     for(int i=1;i<=n;i++)
65         for(int j=1;j<=m;j++)
66             alls[i][j]=read(),ans+=alls[i][j];
67     for(int i=1;i<=n;i++)
68         for(int j=1;j<=m;j++){
69             insert(S,id(i,j),ai[i][j]+alla[i][j]);
70             insert(id(i,j),T,si[i][j]+alls[i][j]);
71             insert(id(i,j),id(i,j)+P,alla[i][j]);
72             insert(id(i,j)+2*P,id(i,j),alls[i][j]);
73             for(int x,y,k=0;k<4;k++){
74                 x=i+dir[k][0],y=j+dir[k][1];
75                 if(x<1 || x>n || y<1 || y>m) continue;
76                 insert(id(i,j)+P,id(x,y),INF);
77                 insert(id(x,y),id(i,j)+2*P,INF);
78             }
79         }
80     printf("%d\n",ans-maxflow());
81     return 0;
82 } 

 

转载于:https://www.cnblogs.com/enigma-aw/p/6228600.html

相关文章:

  • javascript的对象
  • 西门子200实现远程监控和程序调试
  • 简单提高数据库查询效率的办法
  • 记录:CentOS7.2配置LNMP环境记录
  • FLASH遮挡DIV浮动层解决方案兼容IE FF Chrome
  • Linux虚拟机中配置JDK环境变量
  • 常用的集合
  • 中文输入法与React文本输入框的问题与解决方案
  • 树莓派:光阴的故事
  • [转]MVC5 - ASP.NET Identity登录原理 - Claims-based认证和OWIN
  • 追踪记录每笔业务操作数据改变的利器——SQLCDC
  • JS读书心得:《JavaScript框架设计》——第12章 异步处理
  • 2017-1-6基础
  • nodejs npm常用命令
  • Bootstrap的竞争对手Zurb Foundation
  • axios请求、和返回数据拦截,统一请求报错提示_012
  • Bytom交易说明(账户管理模式)
  • CSS中外联样式表代表的含义
  • css属性的继承、初识值、计算值、当前值、应用值
  • ES6核心特性
  • Java IO学习笔记一
  • Java比较器对数组,集合排序
  • Java-详解HashMap
  • Making An Indicator With Pure CSS
  • REST架构的思考
  • Web标准制定过程
  • windows下使用nginx调试简介
  • 大整数乘法-表格法
  • 观察者模式实现非直接耦合
  • 区块链技术特点之去中心化特性
  • 如何学习JavaEE,项目又该如何做?
  • 数据库写操作弃用“SELECT ... FOR UPDATE”解决方案
  • 正则学习笔记
  • 【运维趟坑回忆录 开篇】初入初创, 一脸懵
  • HanLP分词命名实体提取详解
  • 如何用纯 CSS 创作一个货车 loader
  • 曜石科技宣布获得千万级天使轮投资,全方面布局电竞产业链 ...
  • # 飞书APP集成平台-数字化落地
  • #考研#计算机文化知识1(局域网及网络互联)
  • $.proxy和$.extend
  • (14)Hive调优——合并小文件
  • (C语言)二分查找 超详细
  • (Repost) Getting Genode with TrustZone on the i.MX
  • (超简单)构建高可用网络应用:使用Nginx进行负载均衡与健康检查
  • (二)PySpark3:SparkSQL编程
  • (附源码)ssm本科教学合格评估管理系统 毕业设计 180916
  • (附源码)ssm捐赠救助系统 毕业设计 060945
  • (十一)c52学习之旅-动态数码管
  • (四)Android布局类型(线性布局LinearLayout)
  • (详细版)Vary: Scaling up the Vision Vocabulary for Large Vision-Language Models
  • (一)VirtualBox安装增强功能
  • (原创)攻击方式学习之(4) - 拒绝服务(DOS/DDOS/DRDOS)
  • (转)winform之ListView
  • *(长期更新)软考网络工程师学习笔记——Section 22 无线局域网
  • .NET 设计模式初探