Description

文理分科是一件很纠结的事情!(虽然看到这个题目的人肯定都没有纠结过)

小P所在的班级要进行文理分科。他的班级可以用一个n*m的矩阵进行
描述,每个格子代表一个同学的座位。每位同学必须从文科和理科中选择
一科。同学们在选择科目的时候会获得一个满意值。满意值按如下的方式
得到:
1.如果第i行第秒J的同学选择了文科,则他将获得art[i][j]的满意值,如
果选择理科,将得到science[i][j]的满意值。
2.如果第i行第J列的同学选择了文科,并且他相邻(两个格子相邻当且
仅当它们拥有一条相同的边)的同学全部选择了文科,则他会更开
心,所以会增加same_art[i][j]的满意值。
3.如果第i行第j列的同学选择了理科,并且他相邻的同学全部选择了理
科,则增加same_science[i][j]的满意值。
小P想知道,大家应该如何选择,才能使所有人的满意值之和最大。请
告诉他这个最大值。

Solution

妹主席在JZYZ讲过的一道,想起来了于是去切一下

“依然是把最大化收益转化为最小化得不到的收益。
对于每个点,向S和T分别连容量为ai,bi的边,那么V代表划分到A集合的点,V’代表c[s,V’]代表划分到B集合中的元素失去的ai收益,c[V,t]相反,因为选到A集合的点和选到B集合的点相互之间不会产生影响,所以c[V,V’]=0
对于每个附加条件我们额外建立一个点,假设是要求一些元素必须划分到A集合中,那么从源点向它连一条容量为ci的边,从它向要求的元素连一条容量为正无穷的边,这样,割掉源点连向它的边(舍弃掉这个收益)和割掉它连向的所有点连向汇点的边(舍弃掉这些点划分到bi的收益)必须选择其中一个。
点数为O(n+m),边数为O(n+m+sigma(|S|))”
——妹主席的教诲

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<queue>
#define Max(a,b) (a>b?a:b)
#define Min(a,b) (a<b?a:b)
#define INF 0x3f3f3f3f
using namespace std;
int n,m,s,t,level[50005],head[50005],cnt=0,ans=0;
int dx[5]={1,-1,0,0,0},dy[5]={0,0,1,-1,0};
struct Node{int next,to,cap;
}Edges[1000005];
int Read()
{int x=0,f=1;char c=getchar();while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}return x*f;
}
void addedge(int u,int v,int c)
{Edges[cnt].next=head[u];head[u]=cnt;Edges[cnt].to=v;Edges[cnt++].cap=c;
}
void Insert(int u,int v,int c)
{addedge(u,v,c);addedge(v,u,0);
}
int number(int i,int j)
{return (i-1)*m+j;
}
bool bfs()
{memset(level,-1,sizeof(level));queue<int>q;q.push(s);level[s]=0;while(!q.empty()){int u=q.front();q.pop();for(int i=head[u];~i;i=Edges[i].next){int v=Edges[i].to;if(level[v]==-1&&Edges[i].cap)level[v]=level[u]+1,q.push(v);}}if(level[t]==-1)return false;return true;
}
int dfs(int u,int Maxflow)
{if(u==t)return Maxflow;int flow=0,d;for(int i=head[u];~i&&Maxflow>flow;i=Edges[i].next){int v=Edges[i].to;if(level[v]==level[u]+1&&Edges[i].cap){d=dfs(v,Min(Maxflow-flow,Edges[i].cap));Edges[i].cap-=d;Edges[i^1].cap+=d;flow+=d;}}if(!flow)level[u]=-1;return flow;
}
int Dinic()
{int res=0,d;while(bfs()){while(d=dfs(s,INF))res+=d;}return res;
}
int main()
{memset(head,-1,sizeof(head));n=Read(),m=Read();s=0,t=3*n*m+1;for(int i=1;i<=n;i++)for(int j=1;j<=m;j++){int art=Read();ans+=art;Insert(s,number(i,j),art);}for(int i=1;i<=n;i++)for(int j=1;j<=m;j++){int science=Read();ans+=science;Insert(number(i,j),t,science);}for(int i=1;i<=n;i++)for(int j=1;j<=m;j++){int same_art=Read(),p=number(i,j)+m*n;ans+=same_art;Insert(s,p,same_art);for(int k=0;k<5;k++){if(i+dx[k]>0&&i+dx[k]<=n&&j+dy[k]>0&&j+dy[k]<=m)Insert(p,number(i+dx[k],j+dy[k]),INF);}}for(int i=1;i<=n;i++)for(int j=1;j<=m;j++){int same_science=Read(),p=number(i,j)+2*m*n;ans+=same_science;Insert(p,t,same_science);for(int k=0;k<5;k++){if(i+dx[k]>0&&i+dx[k]<=n&&j+dy[k]>0&&j+dy[k]<=m)Insert(number(i+dx[k],j+dy[k]),p,INF);}}printf("%d\n",ans-Dinic());return 0;
}

转载于:https://www.cnblogs.com/Zars19/p/6694937.html

[BZOJ 3894]文理分科(最小割)相关推荐

  1. bzoj 3894: 文理分科 最小割

    Description 文理分科是一件很纠结的事情!(虽然看到这个题目的人肯定都没有纠 结过) 小P所在的班级要进行文理分科.他的班级可以用一个n*m的矩阵进行 描述,每个格子代表一个同学的座位.每位 ...

  2. BZOJ 3894 文理分科 最小割

    题目大意:给定一个m*n的矩阵,每个格子的人可以学文或者学理,学文和学理各有一个满意度,如果以某人为中心的十字内所有人都学文或者学理还会得到一个额外满意度,求最大满意度之和 令S集为学文,T集为学理 ...

  3. [BZOJ 3894]文理分科

    3438: 小M的作物 Time Limit: 10 Sec  Memory Limit: 256 MB Submit: 729  Solved: 328 [Submit][Status][Discu ...

  4. BZOJ 3894 Luogu P4313 文理分科 (最小割)

    题目链接: (bzoj) https://www.lydsy.com/JudgeOnline/problem.php?id=3894 (luogu) https://www.luogu.org/pro ...

  5. 文理分科 (最小割问题)

    Description 文理分科是一件很纠结的事情!(虽然看到这个题目的人肯定都没有纠结过) 小P所在的班级要进行文理分科.他的班级可以用一个n*m的矩阵进行描述,每个格子代表一个同学的座位.每位同学 ...

  6. LuoguP4313 BZOJ3894 文理分科——最小割

    洛谷:文理分科 传送门 题目描述: 小P所在的班级要进行文理分科.他的班级可以用一个n*m的矩阵进行描述,每个格子代表一个同学的座位.每位同学必须从文科和理科中选择一科.同学们在选择科目的时候会获得一 ...

  7. bzoj3894 文理分科 最小割

    Description 文理分科是一件很纠结的事情!(虽然看到这个题目的人肯定都没有纠 结过) 小P所在的班级要进行文理分科.他的班级可以用一个n*m的矩阵进行 描述,每个格子代表一个同学的座位.每位 ...

  8. BZOJ 3894 文理分科

    题解:最小割建模 如果某些元素在一起会得到收益考虑最小割 答案 总收益-最小割 注意:对0点的处理 一开始模型是错的 #include<iostream> #include<cstd ...

  9. bzoj 3894: 文理分科

    Description 文理分科是一件很纠结的事情!(虽然看到这个题目的人肯定都没有纠 结过) 小P所在的班级要进行文理分科.他的班级可以用一个n*m的矩阵进行 描述,每个格子代表一个同学的座位.每位 ...

最新文章

  1. (转) 分布式文件存储FastDFS(七)FastDFS配置文件详解
  2. CoreAnimation —— CAReplicatorLayer(拷贝图层)
  3. java ews_Java---使用EWS 写个ExchangeMailUtil
  4. JavaScript中一个对象数组按照另一个数组排序
  5. 2019年9月数据库流行度排行:MySQL 强劲增长完成深 V 反转
  6. mysql导入报编码错误问题解决
  7. web中ajax实现二级联动,Ajax实现城市二级联动(一)
  8. 实例3 如何使用菜单控件
  9. vue中检测敏感词,锚点
  10. jsonp 返回以前必须要再转一次json
  11. 阶段3 3.SpringMVC·_05.文件上传_1 文件上传之上传原理分析和搭建环境
  12. 【持续更新】组合博弈题目集合
  13. Tapping and Tripping with NFC 基于NFC手机的公共交通票据系统
  14. IP is locked 的解决办法 Vivado
  15. 北京交管部门多举措进行二环慢行系统改造,提升通行安全与效率
  16. SEO怎么获取企业精准流量?
  17. AI芯片:寒武纪PuDianNao结构分析
  18. 安全刻不容缓「GitHub 热点速览 v.21.50」
  19. home brew php71安装,php,_mac home-brew 安装 php 失败,php - phpStudy
  20. oracle sqlnet配置,sqlnet.ora文件配置详解

热门文章

  1. [转] ROS-I simple_message 源码分析:MessageManager
  2. 图解:SQL Server SSIS包和job的部署攻略
  3. excel中定义VBA
  4. 413 Request Entity Too Large
  5. html中的点击事件
  6. Java数据结构——2-3树
  7. [LeetCode]二进制求和
  8. Java语言基础22--访问权限
  9. pytest 15 fixture之autouse=True
  10. j2ee之页面无刷新上传附件