happiness:

Description

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

Input

第一行两个正整数n,m。接下来是六个矩阵第一个矩阵为n行m列 此矩阵的第i行第j列的数字表示座位在第i行第j列的同学选择文科获得的喜悦值。第二个矩阵为n行m列 此矩阵的第i行第j列的数字表示座位在第i行第j列的同学选择理科获得的喜悦值。第三个矩阵为n-1行m列 此矩阵的第i行第j列的数字表示座位在第i行第j列的同学与第i+1行第j列的同学同时选择文科获得的额外喜悦值。第四个矩阵为n-1行m列 此矩阵的第i行第j列的数字表示座位在第i行第j列的同学与第i+1行第j列的同学同时选择理科获得的额外喜悦值。第五个矩阵为n行m-1列 此矩阵的第i行第j列的数字表示座位在第i行第j列的同学与第i行第j+1列的同学同时选择文科获得的额外喜悦值。第六个矩阵为n行m-1列 此矩阵的第i行第j列的数字表示座位在第i行第j列的同学与第i行第j+1列的同学同时选择理科获得的额外喜悦值。

Output

输出一个整数,表示喜悦值总和的最大值

Sample Input

1 2
1 1
100 110
1
1000

Sample Output

1210

【样例说明】
两人都选理,则获得100+110+1000的喜悦值。
【数据规模】
对于100%以内的数据,n,m<=100 所有喜悦值均为小于等于5000的非负整数

首先发现题目出现了很明显的二分图关系--选文科还是理科,很明显是一个网络流问题,联系到题目上的一个人选文科还是理科可以得到一定喜悦值,两个人同时选文科还是理科,又可以得到一定喜悦值,发现最终答案是由每个人选文科,还是选理科,这个行为确定的,与最小割有一定关系。

继续观察,如果按最小割建立模型,每个人选文选理的代价可以在与s,t的连边上体现,这时难点就变成了如何体现两个人之间的关系:同时选文或选理需要的代价。

这时引入一个很神奇的东西,无向边。

这个东西是我在clj的ppt上看见的,有一个很有用的作用:若A<-->B:C,即A与B连一条权值为C的无向边,当这条无向边计入最小割时,表示这两个点分属于s,t两个集合。

但是仅仅知道如此是不够的,因为对于A,B两点,如果他们都属于S集合,即与T集合的边已经计入最小割了,那A与B之间的边就一定不会出现在最小割里,这一点可以作图验证一二。

所以我们应该对原图进行一定变换。注意到这里我们是想将两个点之间的关系体现在同时取s集或同时取t集的情况,即与s,与t的连接边:若A与B同时选文得到W1的喜悦值,同时选理得到W2的喜悦值,S->A:w1/2,A->T:w2/2,

S->B:w1/2,B->T:w2/2,A<-->B:(w1+w2)/2。

为什么呢?自己画图验证,很神奇的东西,特别难想,不过做过一遍以后再做就觉得很容易了。

/**************************************************************
Problem: 2127
User: 1156603280
Language: C++
Result: Accepted
Time:756 ms
Memory:8620 kb
****************************************************************/ #include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <ctime>
#include <cmath>
#define maxn 10000
using namespace std;
int n,m;
int s,t;
int tot=1;
int fir[200000],en[200000],nex[200000],f[200000];
void ins(int a,int b,int c,int d){
nex[++tot]=fir[a];
fir[a]=tot;
en[tot]=b;
f[tot]=c; nex[++tot]=fir[b];
fir[b]=tot;
en[tot]=a;
f[tot]=d; }
int ch[200][200][2]; int flow;
int d[200000],now[200000],num[200000],pre[200000],his[200000];
void sap(){
flow=0;
for (int i=0;i<=t;i++){
now[i]=fir[i];
d[i]=num[i]=0;
}
num[0]=t;
int aug=0x7fffffff;
bool flag;
int i=s;
while (d[s]<t){
his[i]=aug;
flag=false;
for (int k=now[i];k;k=nex[k])
if (f[k]>0&&d[i]==d[en[k]]+1){
aug=min(aug,f[k]);
flag=true;
now[i]=k;
pre[en[k]]=i;
i=en[k];
if (i==t){
flow+=aug;
while (i!=s){
i=pre[i];
f[now[i]]-=aug;
f[now[i]^1]+=aug;
}
aug=0x7fffffff;
}
break;
}
if (flag) continue;
int k1=0,minn=t;
for (int k=fir[i];k;k=nex[k])
if (f[k]>0&&minn>d[en[k]]){
k1=k;
minn=d[en[k]];
}
now[i]=k1;
if (!--num[d[i]]) return;
d[i]=minn+1;
num[d[i]]++; if (i!=s){
i=pre[i];
aug=his[i];
}
} } int sum=0;
int main(){
// freopen("2127.in","r",stdin);
// freopen("2127.out","w",stdout);
scanf("%d%d",&n,&m);
s=n*m+1,t=n*m+2;
for (int i=1;i<=n;i++) //割文 去理
for (int j=1;j<=m;j++){
scanf("%d",&ch[i][j][0]);
sum+=ch[i][j][0];
ch[i][j][0]*=2;
}
for (int i=1;i<=n;i++) //割理 去文
for (int j=1;j<=m;j++){
scanf("%d",&ch[i][j][1]);
sum+=ch[i][j][1];
ch[i][j][1]*=2;
} for (int i=1;i<=n-1;i++)
for (int j=1;j<=m;j++){
int tmp;
scanf("%d",&tmp);
sum+=tmp;
ins((i-1)*m+j,i*m+j,tmp,tmp);
ch[i][j][0]+=tmp;
ch[i+1][j][0]+=tmp;
}
for (int i=1;i<=n-1;i++)
for (int j=1;j<=m;j++){
int tmp;
scanf("%d",&tmp);
sum+=tmp;
ins((i-1)*m+j,i*m+j,tmp,tmp);
ch[i][j][1]+=tmp;
ch[i+1][j][1]+=tmp;
} for (int i=1;i<=n;i++)
for (int j=1;j<=m-1;j++){
int tmp;
scanf("%d",&tmp);
sum+=tmp;
ins((i-1)*m+j,(i-1)*m+j+1,tmp,tmp);
ch[i][j][0]+=tmp;
ch[i][j+1][0]+=tmp;
}
for (int i=1;i<=n;i++)
for (int j=1;j<=m-1;j++){
int tmp;
scanf("%d",&tmp);
sum+=tmp;
ins((i-1)*m+j,(i-1)*m+j+1,tmp,tmp);
ch[i][j][1]+=tmp;
ch[i][j+1][1]+=tmp;
} for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++){
ins(s,(i-1)*m+j,ch[i][j][0],0);
ins((i-1)*m+j,t,ch[i][j][1],0);
}
sap(); printf("%d",sum-flow/2); return 0;
}

[置顶] [BZOJ]2127: happiness 最小割的更多相关文章

  1. BZOJ 2127: happiness [最小割]

    2127: happiness Time Limit: 51 Sec  Memory Limit: 259 MBSubmit: 1815  Solved: 878[Submit][Status][Di ...

  2. BZOJ 2127: happiness(最小割解决集合划分)

    Time Limit: 51 Sec  Memory Limit: 259 MBSubmit: 2350  Solved: 1138[Submit][Status][Discuss] Descript ...

  3. [BZOJ 2127] happiness 【最小割】

    题目链接:BZOJ - 2127 题目分析 首先,每个人要么学文科,要么学理科,所以可以想到是一个最小割模型. 我们就确定一个人如果和 S 相连就是学文,如果和 T 相连就是学理. 那么我们再来确定建 ...

  4. BZOJ 2127 / Luogu P1646 [国家集训队]happiness (最小割)

    题面 BZOJ传送门 Luogu传送门 分析 这道题又出现了二元关系,于是我们只需要解方程确定怎么连边就行了 假设跟SSS分在一块是选文科,跟TTT分在一块是选理科,先加上所有的收益,再来考虑如何让需 ...

  5. [国家集训队]happiness 最小割 BZOJ 2127

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

  6. bzoj 2127 happiness【最小割+dinic】

    参考:https://www.cnblogs.com/chenyushuo/p/5144957.html 不得不说这个建图方法真是非常妙啊 假设S点选理,T点选文,a[i][j]为(i,j)选文收益, ...

  7. [bzoj2127]happiness——最小割

    这个题太恶心了...并不想继续做了... 本代码在bzoj上TLE! 大致说一下思路: 建立ST,首先由S连边(S,u,a)a代表学文的分数,连向T(u,T,b)b表示学理的分数,这样构造出了两个人独 ...

  8. spoj 839 OPTM - Optimal Marks&&bzoj 2400【最小割】

    因为是异或运算,所以考虑对每一位操作.对于所有已知mark的点,mark的当前位为1则连接(s,i,inf),否则连(i,t,inf),然后其他的边按照原图连(u,v,1),(v,u,1),跑最大流求 ...

  9. BZOJ 3144 切糕 最小割

    题意: 一个矩阵,每个格子分配一个数,不同的数字,代价不同,要求相邻格子数字差小等于d 求最小代价. 分析: 我猜肯定有人看题目就想到最小割了,然后一看题面理科否决了自己的这个想法…… 没错,就是最小 ...

随机推荐

  1. IIS会话过期的问题/WCF日志管理

    http://technet.microsoft.com/zh-cn/library/cc725624(v=ws.10).aspx http://msdn.microsoft.com/zh-cn/li ...

  2. android SharedPreferences 使用

    除了SQLite数据库外,SharedPreferences也是一种轻型的数据存储方式,它的本质是基于XML文件存储key-value键值 对数据,通常用来存储一些简单的配置信息.其存储位置在/dat ...

  3. C# 设置鼠标指针

    鼠标光标指针的使用 #region 设置鼠标指针 //设置鼠标指针 //Cursor cus = new Cursor(@"C:\Users\Public\Pictures\Sample P ...

  4. Nandflash 驱动移植

    前段时间,研究了一下4G的Nandflash驱动.手头上只有飞凌6410BSP自带的Nandflash驱动,该驱动不支持K9GAG08U0D(2G)和K9LBG08U0D(4G)的Nandflash. ...

  5. 转:LayoutInflater作用及使用

    作用: 1.对于一个没有被载入或者想要动态载入的界面, 都需要使用inflate来载入. 2.对于一个已经载入的Activity, 就可以使用实现了这个Activity的的findViewById() ...

  6. pylinter could not automatically determined the path to `lint.py`

    先关闭Sublime Text 1) 到官网先下载pylinter,http://www.logilab.org/project/pylint,然后解压缩,拷贝到C盘,目录为C:\pylint-1.0 ...

  7. poj 1159 Palindrome(dp)

    题目:http://poj.org/problem?id=1159 #include<iostream> #include<cstring> #include<cstdi ...

  8. 使用HQL查询

    HQL是Hibernate Query Language的缩写,语法很想SQL,但是HQL是一种面向对象的查询语言.SQL的操作对象是数据列.表等数据库对象,而HQL操作的是类.实例.属性. HQL查 ...

  9. 比较const ,readonly, stitac readonly

    比较const ,readonly, stitac readonly: const和readonly的值一旦初始化则都不再可以改写: const必须在声明时初始化:readonly既可以在声明时初始化 ...

  10. sencha touch 2 tabpanel中List的不显示问题,解决方案

    笔者在做sencha项目的时候碰到一个需求,就是"好友列表"中分为"未确认好友"和"已确认好友",两个都是一个list,自然想到的就是使用t ...