分析:

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

我们先这样考虑,将和选理相关的和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. 【代码笔记】iOS-performSelectorOnMainThread

    代码: RootViewController.h #import <UIKit/UIKit.h> @interface RootViewController : UIViewControl ...

  2. bootstrap datetimepicker日期插件美化

    效果 https://segmentfault.com/img/bVbieIp?w=1029&h=461 原文链接:https://segmentfault.com/a/11900000167 ...

  3. 全局eslint不生效的处理

    react项目里能用上 eslint 的 airbnb 规范真是的,对自己的编码有很好的帮助,不经可以养成良好的代码风格,而且还能检测出 state或者变量 是否 使用过, 然而,所在团队的小伙伴们, ...

  4. Mac 上用 Homebrew 安装 .NET Core 1.0 RC4 004771

    年级大了,其实并不是很喜欢升级到最新版,特别是不怎么爱用还没有 Release 的版本了.虽然 .NET Core 已经是 RC4,但毕竟还没有 Release.可过年回来,用 yeoman 创建了一 ...

  5. jQuery同步Ajax带来的UI线程阻塞问题

    一.需求 在调ajax接口的时候因为有时间延迟,想要做一个loading加载的效果,等数据返回时再把loading的效果去掉. 所以我在调ajax的代码块前面加了显示loading效果的代码,ajax ...

  6. 在Android Native层中创建Java虚拟机实例

    前言 Android应用中JNI代码,是作为本地方法运行的.而大部分情况下,这些JNI方法均需要传递Dalvik虚拟机实例作为第一个参数.例如,你需要用虚拟机实例来创建jstring和其他的Java对 ...

  7. 用VisualAssist在Visual Studio上设置快捷键快速编程

    一  在Visual Studio上安装VisualAssist工具: 链接:https://pan.baidu.com/s/1uaeRFTvY4p7LNoDvQFEU5A 提取码:j1ws 安装后, ...

  8. windows 7 下安装Oracle 9i 解决方法[转]

    这里首先申明下,windows7下安装oracle9i 9.0.1版本肯定是不成功的,楼主安装过无数次,网上也找过很多方法,都不可行,所以就不用试了.这里说下oracle9i 9.2版本安装出现的问题 ...

  9. mysql的几个知识点

    常用命令 原则:能用可视化工具的尽量使用工具,命令行仅限于问题排查. mysql -u ACCOUNT -pPWD -h IP -P port [-D database] //连接数据库 show d ...

  10. LeetCode题解之Max Consecutive Ones

    1.题目描述 2.问题分析 遍历一次数组,以每个1 为起点向后数,数到0 时比较当前1的个数和最大1 的个数,然后将遍历的起点放到当前0 的后面. 3.代码 int findMaxConsecutiv ...