分析:

最小割(一开始我没看出来...后来经过提点,大致理解...),不选则割的思想。

我们先这样考虑,将和选理相关的和S相连,与选文相关的和T相连,如果没有第二问,那么建图就是简单的S连cnt,cnt连T,流量分别为对应的喜悦值,那么在这个图的基础上,考虑第二问,因为我们需要将所有不选的边割掉,那么,我们可以考虑新建两个点,一个连接S,流量为喜悦值,一个连接T,流量为喜悦值,那么将这两个节点连向相应的要求节点(比如两个人同时学理/文),流量为inf,这样,我们每次割掉一个S连向cnt的边的时候,必须将所有的S连向tot的边割掉,就相当于是题目的要求了,最后得到最小割,用总和减去最小割就好了。

附上代码:(文理分科)

#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <iostream>
#include <queue>
#include <cstdlib>
using namespace std;
#define N 30005
#define p(i,j) ((i-1)*m+j)
#define inf 10000000
#define S 0
#define T 30004
int head[N],cnt,dep[N],a[105][105],b[105][105],sum,n,m;
struct node
{
int to,next,val;
}e[1000010];
int dx[4]={0,1,-1,0};int dy[4]={1,0,0,-1};
void add(int x,int y,int z){e[cnt].to=y;e[cnt].next=head[x];e[cnt].val=z;head[x]=cnt++;}
void insert(int x,int y,int z){add(x,y,z);add(y,x,0);}
int bfs()
{
memset(dep,-1,sizeof(dep));
queue <int>q;q.push(S);dep[S]=1;
while(!q.empty())
{
int x=q.front();q.pop();
for(int i=head[x];i!=-1;i=e[i].next)
{
int to1=e[i].to;
if(dep[to1]==-1&&e[i].val)dep[to1]=dep[x]+1,q.push(to1);
}
}
return dep[T]==-1?0:1;
}
int dfs(int x,int maxf)
{
if(x==T)return maxf;
int tflow=maxf,nowf;
for(int i=head[x];i!=-1;i=e[i].next)
{
int to1=e[i].to;
if(dep[to1]==dep[x]+1&&e[i].val)
{
nowf=dfs(to1,min(e[i].val,tflow));
if(!nowf)dep[to1]=-1;
tflow-=nowf,e[i].val-=nowf,e[i^1].val+=nowf;
if(!tflow)break;
}
}
return maxf-tflow;
}
int main()
{
memset(head,-1,sizeof(head));
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
int x;
scanf("%d",&x);sum+=x;
insert(S,p(i,j),x);
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
int x;
scanf("%d",&x);sum+=x;
insert(p(i,j),T,x);
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
scanf("%d",&a[i][j]);sum+=a[i][j];
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
scanf("%d",&b[i][j]);sum+=b[i][j];
}
}
int tot=n*m;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
tot+=2;
insert(S,tot-1,a[i][j]);insert(tot,T,b[i][j]);
insert(tot-1,p(i,j),inf);insert(p(i,j),tot,inf);
for(int k=0;k<4;k++)
{
int tx=dx[k]+i,ty=dy[k]+j;
if(tx>=1&&tx<=n&&ty<=m&&ty>=1)
{
insert(tot-1,p(tx,ty),inf);
insert(p(tx,ty),tot,inf);
}
}
}
}
int ans=0;
while(bfs())ans+=dfs(S,1<<30);
printf("%d\n",sum-ans);
return 0;
}

附上代码:(happiness)

#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <iostream>
#include <queue>
#include <cstdlib>
using namespace std;
#define N 60005
#define p(i,j) ((i-1)*m+j)
#define inf 10000000
#define S 0
#define T 60004
int head[N],cnt,dep[N],a[105][105],b[105][105],n,m;long long sum;
struct node
{
int to,next,val;
}e[2000010];
int dx[4]={0,1,-1,0};int dy[4]={1,0,0,-1};
void add(int x,int y,int z){e[cnt].to=y;e[cnt].next=head[x];e[cnt].val=z;head[x]=cnt++;}
void insert(int x,int y,int z){add(x,y,z);add(y,x,0);}
int bfs()
{
memset(dep,-1,sizeof(dep));
queue <int>q;q.push(S);dep[S]=1;
while(!q.empty())
{
int x=q.front();q.pop();
for(int i=head[x];i!=-1;i=e[i].next)
{
int to1=e[i].to;
if(dep[to1]==-1&&e[i].val)dep[to1]=dep[x]+1,q.push(to1);
}
}
return dep[T]==-1?0:1;
}
int dfs(int x,int maxf)
{
if(x==T)return maxf;
int tflow=maxf,nowf;
for(int i=head[x];i!=-1;i=e[i].next)
{
int to1=e[i].to;
if(dep[to1]==dep[x]+1&&e[i].val)
{
nowf=dfs(to1,min(e[i].val,tflow));
if(!nowf)dep[to1]=-1;
tflow-=nowf,e[i].val-=nowf,e[i^1].val+=nowf;
if(!tflow)break;
}
}
return maxf-tflow;
}
int main()
{
memset(head,-1,sizeof(head));
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
int x;
scanf("%d",&x);sum+=x;
insert(S,p(i,j),x);
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
int x;
scanf("%d",&x);sum+=x;
insert(p(i,j),T,x);
}
}
for(int i=1;i<n;i++)
{
for(int j=1;j<=m;j++)
{
scanf("%d",&a[i][j]);sum+=a[i][j];
}
}
for(int i=1;i<n;i++)
{
for(int j=1;j<=m;j++)
{
scanf("%d",&b[i][j]);sum+=b[i][j];
}
}
int tot=n*m;
for(int i=1;i<n;i++)
{
for(int j=1;j<=m;j++)
{
tot+=2;
insert(S,tot-1,a[i][j]);insert(tot,T,b[i][j]);
insert(tot-1,p(i,j),inf);insert(tot-1,p(i+1,j),inf);
insert(p(i,j),tot,inf);insert(p(i+1,j),tot,inf);
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<m;j++)
{
scanf("%d",&a[i][j]);sum+=a[i][j];
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<m;j++)
{
scanf("%d",&b[i][j]);sum+=b[i][j];
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<m;j++)
{
tot+=2;
insert(S,tot-1,a[i][j]);insert(tot,T,b[i][j]);
insert(tot-1,p(i,j),inf);insert(tot-1,p(i,j+1),inf);
insert(p(i,j),tot,inf);insert(p(i,j+1),tot,inf);
}
}
long long ans=0;
while(bfs())ans+=dfs(S,1<<30);
printf("%d\n",sum-ans);
return 0;
}

  

文理分科 BZOJ3894 & happiness BZOJ2127的更多相关文章

  1. [bzoj3894]文理分科_网络流_最小割

    文理分科 bzoj-3894 题目大意:题目链接. 注释:略. 想法: 这种题也是一种套路. 我们新建一个点表示收益点. 然后把所有的收益都加一起,求最小割表示代价即可. Code: #include ...

  2. 【BZOJ3894】文理分科(最小割)

    [BZOJ3894]文理分科(最小割) 题面 BZOJ Description 文理分科是一件很纠结的事情!(虽然看到这个题目的人肯定都没有纠 结过) 小P所在的班级要进行文理分科.他的班级可以用一个 ...

  3. 【BZOJ3894】文理分科 最小割

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

  4. 【bzoj3894】文理分科 网路流

    [bzoj3894]文理分科 2015年3月25日3,4002 Description  文理分科是一件很纠结的事情!(虽然看到这个题目的人肯定都没有纠 结过)  小P所在的班级要进行文理分科.他的班 ...

  5. Bzoj3894 文理分科

    Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 667  Solved: 389 Description  文理分科是一件很纠结的事情!(虽然看到这个题 ...

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

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

  7. 【BZOJ3894】文理分科

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

  8. BZOJ3894:文理分科(最大流)(同BZoj3438)

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

  9. BZOJ3894:文理分科——题解

    http://www.lydsy.com/JudgeOnline/problem.php?id=3894 文理分科是一件很纠结的事情!(虽然看到这个题目的人肯定都没有纠结过) 小P所在的班级要进行文理 ...

随机推荐

  1. short、int、long、float、double区别

    一.基本数据类型的特点,位数,最大值和最小值.1.基本类型:short 二进制位数:16 包装类:java.lang.Short 最小值:Short.MIN_VALUE=-32768 (-2的15此方 ...

  2. JS数组和对象的浅拷贝和深拷贝

    共勉~ 在许多编程语言中,传递参数和赋值是通过值的直接复制或者引用复制完成的.在JavaScript中,对于值是直接进行复制还是引用复制在语法上是没有区别的,完全是根据值的类型来决定的. 在JavaS ...

  3. OSGI企业应用开发(三)Eclipse中搭建Equinox运行环境

    上篇文章介绍了如何在Eclipse中搭建Felix的运行环境,我们需要將Bundle发布到Felix框架的bundle目录下,Felix框架启动时才会自动加载这些Bundle,否则需要在Felix框架 ...

  4. python学习笔记之——python面向对象

    Python是一门面向对象语言. 1.面向对象技术介绍 类(Class): 用来描述具有相同的属性和方法的对象的集合.它定义了该集合中每个对象所共有的属性和方法.对象是类的实例. 类变量:类变量在整个 ...

  5. linux 网络和流量监控

    1.流量监控 工具iptraf 安装:sudo apt-get install iptraf 运行:sudo iptraf   2.网络监控扫描 参考:https://www.cnblogs.com/ ...

  6. Android Relative Layout 安卓相对布局详解

    思维导图可在幕布找到 1. 基础 如果在相对布局里,控件没有指明相对位置,则默认都是在相对布局的左上角: <TextView android:layout_width="wrap_co ...

  7. Jboss7或者wildfly部署war包的问题 1

    1.Jboss的日志系统(standalone模式) 在介绍案例分析之前先来介绍一下Jboss提供的日志系统,下载EAP的zip包解压后的结构如下: 在standalone目录下有两个文件standa ...

  8. 在命令行中创建Django项目

    1.终端先进入你要放项目的目录. 在命令行输入:django-admin startproject 项目名  .回车,此时创建了一个项目. 例:django-admin startproject my ...

  9. 转:ASP.NET MVC 多语言实现技巧 最简、最易维护和最快速开发

    说说传统做法的缺点 1.做过多语言的都知道这玩意儿太花时间 2.多语言架构一般使用资源文件.XML或者存储数据库来实现.这样就在一定程序上降低了性能 3.页面的可读性变差,需要和资源文件进行来回切换 ...

  10. C# 引用的程序集没有强名称

    首先查一下什么是强名称程序集,见百度百科帖子:http://baike.baidu.com/view/1145682.htm简单来说,就是为了解决Windows Dll Hell问题的,即不同公司开发 ...