【2011集训队出题】happiness
来源:互联网 发布:java 二分法排序代码 编辑:程序博客网 时间:2024/05/08 14:10
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
Hint
【样例说明】
两人都选理,则获得100+110+1000的喜悦值。
【数据规模】
对于10%以内的数据,n,m<=4
对于30%以内的数据,n,m<=8
对于100%以内的数据,n,m<=100 所有喜悦值均为小于等于5000的非负整数
Solution
同样是二元关系
感觉和圈地计划很像,但是这题的收益却不是同一个,而是不同的
这题就稍微推理一下
同样是取最大值,所以取反
两个人A,B
A文B文=-A文-B文-同文
A文B理=-A文-B文
A理B理=-A理-B理-同理
A理B文=-A理-B文
加上所有的收益(A文+B文+A理+B理+同文+同理)
变成
A文B文=A理+B理+同理
A文B理=A理+B文+同理+同文
A理B理=A文+B文+同文
A理B文=A文+B文+同理+同文
然后平分
已第一个为例
A文->A理+0.5*同理
B文->B理+0.5*同理
然后…………
最后的连边
源点向所有点连 文+0.5同文
所有点向汇点连 理+0.5同理
相邻的点(有关系的点) 连 0.5同文+0.5同理
这里的0.5同文或0.5同理都是对周围所有点的和
为了方便,可以先将所有点的权值*2变成整数,最后再/2
答案就是所有的和-最小割
Code
#include<cstdio>#include<algorithm>#include<cmath>#include<cstring>#define fo(i,a,b) for(int i=a;i<=b;i++)#define no(x,y) ((x-1)*m+y)#define N 101using namespace std;int n,m,s,t,a[N][N],b[N][N],c[N][N],d[N][N],e[N][N],q[N][N],qu[555555],bz[555555],ans=0,next[555555],last[555555],to[555555],data[555555],tot=1;void putin(int x,int y,int z,int z1){ next[++tot]=last[x];last[x]=tot;to[tot]=y;data[tot]=z; next[++tot]=last[y];last[y]=tot;to[tot]=x;data[tot]=z1;}bool bfs(){ int i=0,j=1;qu[1]=s;memset(bz,0,sizeof(bz));bz[s]=1; while(i<j) { int l=qu[++i]; for(int k=last[l];k;k=next[k]) if(data[k]>0&&bz[to[k]]==0) bz[to[k]]=bz[l]+1,qu[++j]=to[k]; } return bz[t]!=0;}int dfs(int x,int v){ if(x==t) return v;int ans=0; for(int i=last[x];i;i=next[i]) { int y=to[i]; if(bz[y]==bz[x]+1&&data[i]>0) { int qq=dfs(y,min(v,data[i])); if(qq) data[i]-=qq,data[i^1]+=qq,ans+=qq,v-=qq; if(v==0) return ans; } } if(ans==0) bz[x]=-1; return ans;}int main(){ scanf("%d%d",&n,&m);s=n*m+1;t=n*m+2; fo(i,1,n) fo(j,1,m) scanf("%d",&a[i][j]),ans+=2*a[i][j]; fo(i,1,n) fo(j,1,m) scanf("%d",&b[i][j]),ans+=2*b[i][j]; fo(i,1,n-1) fo(j,1,m) scanf("%d",&c[i][j]),ans+=2*c[i][j]; fo(i,1,n-1) fo(j,1,m) scanf("%d",&d[i][j]),ans+=2*d[i][j]; fo(i,1,n) fo(j,1,m-1) scanf("%d",&e[i][j]),ans+=2*e[i][j]; fo(i,1,n) fo(j,1,m-1) scanf("%d",&q[i][j]),ans+=2*q[i][j]; fo(i,1,n) fo(j,1,m) { putin(s,no(i,j),2*a[i][j]+c[i][j]+c[i-1][j]+e[i][j]+e[i][j-1],0); putin(no(i,j),t,2*b[i][j]+d[i][j]+d[i-1][j]+q[i][j]+q[i][j-1],0); int x=i,y=j+1; if(x<=n&&y<=m) putin(no(i,j),no(x,y),q[i][j]+e[i][j],q[i][j]+e[i][j]); x=i+1,y=j; if(x<=n&&y<=m) putin(no(i,j),no(x,y),c[i][j]+d[i][j],c[i][j]+d[i][j]); } while(bfs()) ans-=dfs(s,214748368); printf("%d",ans/2);}
- 【2011集训队出题】happiness
- 【2011集训队出题】happiness
- [JZOJ1919] [BZOJ2127]【2011集训队出题】happiness(最小割之二元关系)
- 【2011集训队出题】圈地计划
- 【2011集训队出题】数颜色
- 【集训队出题2011】大楼 题解
- [国家集训队2011]happiness(吴确)…
- 【COGS 1873】 [国家集训队2011]happiness(吴确)
- 最小割 [国家集训队2011]happiness(吴确)
- 【国家集训队2011】happiness 网络最大流
- [国家集训队2011]happiness(吴确) (最小割)
- 【数学】2011集训队出题 跳跳棋
- 【2011集训队出题】Crash的数字表格
- 【2011集训队出题】Crash的数字表格
- 【2011集训队出题】【GDKOI2010】圈地计划
- JZOJsenior1935.【2011集训队出题】单选错位
- jzoj1916 [2011集训队出题] 飞飞侠 spfa
- jzoj1935 [2011集训队出题] 单选错位 概率水题
- JSP
- 双线性插值
- springmvc笔记01
- 第11节--支持向量机(SVM)--线性不可分
- Oracle数据库Timestamp数据差值计算Sql语句
- 【2011集训队出题】happiness
- POJ2195 Going Home
- JavaScript跨域问题之CORS方法与JSONP的对比
- 【设计模式系列】--单例模式
- 消息队列设计
- 详细记录python的range()函数用法
- 数据库优化
- Android APK反编译 apktool使用教程
- Java学习笔记1