题目描述

高一一班的座位表是个n*m的矩阵,经过一个学期的相处,每个同学和前后左右相邻的同学互相成为了好朋友。这学期要分文理科了,每个同学对于选择文科与理科有着自己的喜悦值,而一对好朋友如果能同时选文科或者理科,那么他们又将收获一些喜悦值。作为计算机竞赛教练的scp大老板,想知道如何分配可以使得全班的喜悦值总和最大。

题解

这道题相当于给了我们一堆二元关系。容易想到用二元关系最小割来解决。

我们设学文的收益为w,学理的收益为l,同时学文的收益为w‘,同时学理的收益为w’。

那么考虑割集。

\[S_x+S_y=w_x+w_y+w‘
\]

\[T_x+T_y=l_x+l_y+l'
\]

\[S_x+w1+T_y=w_y+l_+w'+l'
\]

\[S_y+w2+T_x=w_x+l_y+w'+l'
\]

弄完之后发现有分数,乘个2就好了。

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define N 30009
#define M 109
#define inf 1e9
using namespace std;
queue<int>q;
const int dx[4]={0,0,1,-1};
const int dy[4]={1,-1,0,0};
int num,tot=1,head[N],cur[N],deep[N],n,m,a[M][M],s_a[M][M],s[M][M],s_s[M][M],id[M][M];
long long ans;
inline int rd(){
int x=0;char c=getchar();bool f=0;
while(!isdigit(c)){if(c=='-')f=1;c=getchar();}
while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return f?-x:x;
}
struct edge{
int n,to,l;
}e[N*30];
inline void add(int u,int v,int l,int tag){
e[++tot].n=head[u];e[tot].to=v;head[u]=tot;e[tot].l=l;
e[++tot].n=head[v];e[tot].to=u;head[v]=tot;e[tot].l=l*tag;
}
bool bfs(int s,int t){
memcpy(cur,head,sizeof(head));
memset(deep,0,sizeof(deep));
q.push(s);deep[s]=1;
while(!q.empty()){
int u=q.front();q.pop();
for(int i=head[u];i;i=e[i].n){
int v=e[i].to;
if(!deep[v]&&e[i].l){
deep[v]=deep[u]+1;
q.push(v);
}
}
}
return deep[t];
}
int dfs(int u,int t,int l){
if(u==t||!l)return l;
int flow=0,f;
for(int &i=cur[u];i;i=e[i].n){
int v=e[i].to;
if(deep[v]==deep[u]+1&&(f=dfs(v,t,min(l,e[i].l)))){
e[i].l-=f;e[i^1].l+=f;flow+=f;l-=f;
if(!l)break;
}
}
return flow;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)a[i][j]=rd()*2,id[i][j]=++num,ans+=a[i][j];
int S=0,T=num+1;
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)s[i][j]=rd()*2,ans+=s[i][j];
for(int i=1;i<n;++i)
for(int j=1;j<=m;++j){
s_a[i][j]=rd();ans+=s_a[i][j]*2;
a[i][j]+=s_a[i][j],a[i+1][j]+=s_a[i][j];
}
for(int i=1;i<n;++i)
for(int j=1;j<=m;++j){
s_s[i][j]=rd();ans+=s_s[i][j]*2;
s[i][j]+=s_s[i][j];s[i+1][j]+=s_s[i][j];
add(id[i][j],id[i+1][j],s_a[i][j]+s_s[i][j],1);
}
for(int i=1;i<=n;++i)
for(int j=1;j<m;++j){
s_a[i][j]=rd();ans+=s_a[i][j]*2;
a[i][j]+=s_a[i][j],a[i][j+1]+=s_a[i][j];
}
for(int i=1;i<=n;++i)
for(int j=1;j<m;++j){
s_s[i][j]=rd();ans+=s_s[i][j]*2;
s[i][j]+=s_s[i][j];s[i][j+1]+=s_s[i][j];
add(id[i][j],id[i][j+1],s_a[i][j]+s_s[i][j],1);
}
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)add(S,id[i][j],a[i][j],0),add(id[i][j],T,s[i][j],0);
while(bfs(S,T))ans-=dfs(S,T,inf);
ans/=2;
cout<<ans;
return 0;
}

BZOJ2127Happiness的更多相关文章

  1. BZOJ-2127-happiness(最小割)

    2127: happiness(题解) Time Limit: 51 Sec  Memory Limit: 259 MBSubmit: 1806  Solved: 875 Description 高一 ...

  2. BZOJ2127happiness——最小割

    题目描述 高一一班的座位表是个n*m的矩阵,经过一个学期的相处,每个同学和前后左右相邻的同学互相成为了好朋友.这学期要分文理科了,每个同学对于选择文科与理科有着自己的喜悦值,而一对好朋友如果能同时选文 ...

  3. bzoj2127happiness(最小割)

    一眼最小割. 一种比较好想的建图方式如下: 连源点表示学文,连汇点表示学理,然后adde(S,id(i,j),a[i][j]),adde(id(i,j),T,b[i][j]):对于相邻座位选择同一科的 ...

  4. BZOJ2132 圈地计划 【最小割】

    题目 最近房地产商GDOI(Group of Dumbbells Or Idiots)从NOI(Nuts Old Idiots)手中得到了一块开发土地.据了解, 这块土地是一块矩形的区域,可以纵横划分 ...

随机推荐

  1. C# winForm 窗口跳转后关闭上一个窗口的方法

    FrmMain main = new FrmMain(); main.Owner = this; this.Hide(); main.ShowDialog(); Application.ExitThr ...

  2. PLSQL 登录出现 ora12638 credential retrieval failed

    参考:http://blog.csdn.net/yjq8116/article/details/4203168 解决了 开始 -> 程序 -> Oracle -> Configura ...

  3. C# 委托还能这样用

    一直找不到一种能够让很多对象都能在几乎同时接收到通知的方法.介绍下目前在用的,希望能够抛砖引玉. 首先随便贴一下观察者模式的两接口,观察者模式自行搜索设计模式. public interface IS ...

  4. vue鼠标悬停事件

    v-bind:title="message" <!DOCTYPE html> <html lang="en"> <head> ...

  5. Spring Boot 入门(五):集成 AOP 进行日志管理

    本篇文章是接着 Spring boot 入门(四):集成 Shiro 实现登陆认证和权限管理写的,按照前面几篇博客的教程,可以搭建一个简单的项目,主要包含了 Pagehelper+MyBatis 分页 ...

  6. Java的SSH框架整合

    写了好多篇的Android代码了,在写几篇关于Java的,博客园里肯定都是java的前辈啊,写的不好多给意见. SSH,什么是SSH呢,Struts+Spring+Hibernate,这三个就是整个的 ...

  7. Android 注解框架对比

    Java的注解(Annotation)相当于一种标记,在程序中加入注解就等于为程序打上某种标记,标记可以加在包,类,属性,方法,本地变量上.然后你可以写一个注解处理器去解析处理这些注解(人称编译时注解 ...

  8. 西湖论剑2019-msc之奇怪的TTL

    msc1给了一串很长的TTL字符,参考一些隐写的文章,猜测是在ttl中藏了信息,题目是这样的 我们截获了一些IP数据报,发现报文头中的TTL值特别可疑,怀疑是通信方嵌入了数据到TTL,我们将这些TTL ...

  9. C++11のlambd表达式

    在其他语言中,我们常见lambda表达式,c++11中也引入了. 利用Lambda表达式,可以方便的定义和创建匿名函数.今天,我们就来简单介绍一下C++中Lambda表达式的简单使用. 一.lambd ...

  10. mybatis批量插入报错

    报错内容 org.springframework.jdbc.UncategorizedSQLException: ### Error updating database. Cause: java.sq ...