博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BZOJ3894: 文理分科
阅读量:4974 次
发布时间:2019-06-12

本文共 2940 字,大约阅读时间需要 9 分钟。

【传送门:】


简要题意:

  给出六个矩阵描述n*m个人选择文科理科的情况

  第一个矩阵(n*m):A[i][j]表示第i行第j列的人选择文科的喜悦值

  第二个矩阵(n*m):B[i][j]表示第i行第j列的人选择理科的喜悦值

  第三个矩阵(n*m):C[i][j]表示第i行第j列的人选择文科并且上下左右的人都选择文科的喜悦值

  第三个矩阵(n*m):D[i][j]表示第i行第j列的人选择理科并且上下左右的人都选择理科的喜悦值

  求出最大喜悦值


题解:

  和BZOJ2127的题意相似

  也是最小割

  对于i和i相邻的人,新开一个点

  将st连向这些人和新开的点,流量为选文科的喜悦值

  将i和i相邻的人连向一个新开的点,流量为无穷大

  将这个新开的点连向ed,流量为C[i][j]

  这样子,就表示集合内任意一个人学理都要把这个点与T的边割掉

  对于理科的连边同理,但理科要反向连边


参考代码:

#include
#include
#include
#include
#include
using namespace std;int A[110][110],B[110][110],C[110][110],D[110][110];struct node{ int x,y,c,next,other;}a[2100000];int len,last[31000];void ins(int x,int y,int c){ int k1=++len,k2=++len; a[k1].x=x;a[k1].y=y;a[k1].c=c; a[k1].next=last[x];last[x]=k1; a[k2].x=y;a[k2].y=x;a[k2].c=0; a[k2].next=last[y];last[y]=k2; a[k1].other=k2; a[k2].other=k1;}int h[31000],list[31000];int st,ed;bool bt_h(){ memset(h,0,sizeof(h));h[st]=1; list[1]=st; int head=1,tail=2; while(head!=tail) { int x=list[head]; for(int k=last[x];k;k=a[k].next) { int y=a[k].y; if(a[k].c>0&&h[y]==0) { h[y]=h[x]+1; list[tail++]=y; } } head++; } if(h[ed]==0) return false; else return true;}int findflow(int x,int f){ if(x==ed) return f; int s=0,t; for(int k=last[x];k;k=a[k].next) { int y=a[k].y; if(h[y]==h[x]+1&&a[k].c>0&&f>s) { t=findflow(y,min(a[k].c,f-s)); s+=t; a[k].c-=t; a[a[k].other].c+=t; } } if(s==0) h[x]=0; return s;}int d[110][110];int dx[5]={
0,1,-1,0,0};int dy[5]={
0,0,0,1,-1};int main(){ int n,m; scanf("%d%d",&n,&m);int s=0; st=0;ed=3*n*m+1; int cnt=0; len=0;memset(last,0,sizeof(last)); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) d[i][j]=++cnt; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++){scanf("%d",&A[i][j]);ins(st,d[i][j],A[i][j]);s+=A[i][j];} for(int i=1;i<=n;i++) for(int j=1;j<=m;j++){scanf("%d",&B[i][j]);ins(d[i][j],ed,B[i][j]);s+=B[i][j];} for(int i=1;i<=n;i++) for(int j=1;j<=m;j++){scanf("%d",&C[i][j]);s+=C[i][j];} for(int i=1;i<=n;i++) for(int j=1;j<=m;j++){scanf("%d",&D[i][j]);s+=D[i][j];} for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { ins(st,d[i][j]+n*m,C[i][j]); ins(d[i][j]+2*n*m,ed,D[i][j]); for(int k=0;k<=4;k++) { int tx=i+dx[k],ty=j+dy[k]; if(tx<1||ty<1||tx>n||ty>m) continue; ins(d[i][j]+n*m,d[tx][ty],999999999); ins(d[tx][ty],d[i][j]+2*n*m,999999999); } } } int ans=0; while(bt_h()) { ans+=findflow(st,999999999); } printf("%d\n",s-ans); return 0;}

 

转载于:https://www.cnblogs.com/Never-mind/p/8341453.html

你可能感兴趣的文章
poj2594——最小路径覆盖
查看>>
程序员口述:我是如何工作三年后跳槽到美团的?
查看>>
欧拉函数
查看>>
关于SQL2008 “不允许保存更改。您所做的更改要求删除并重新创建以下表。您对无法重新创建的标进行了更改或者启用了‘阻止保存要求重新创建表的更改’” 解决方案...
查看>>
php文件操作(上传文件)2
查看>>
linux内核驱动模型
查看>>
给WebApp加一个“壳”,实现Andriod系统添加到桌面
查看>>
js 浏览器复制功能
查看>>
数据库总编
查看>>
redis 字符串(string)函数
查看>>
杭州电 1372 Knight Moves(全站搜索模板称号)
查看>>
POJ--3268--Silver Cow Party【SPFA+邻接表】
查看>>
c语言的几个简单memo
查看>>
C#的默认访问权限
查看>>
selenium下打开Chrome报错解决
查看>>
红酒初识
查看>>
BNUOJ 5629 胜利大逃亡(续)
查看>>
HDU-1150 Machine Schedule(二分图、匈牙利)
查看>>
Python assert 断言函数
查看>>
Android 学习笔记之ContentProvider实现数据共享....
查看>>