3894: 文理分科

Time Limit: 10 Sec Memory Limit: 512 MB
Submit: 194 Solved: 122
[Submit][Status][Discuss]
Description

文理分科是一件很纠结的事情!(虽然看到这个题目的人肯定都没有纠
结过)
小P所在的班级要进行文理分科。他的班级可以用一个n*m的矩阵进行
描述,每个格子代表一个同学的座位。每位同学必须从文科和理科中选择
一科。同学们在选择科目的时候会获得一个满意值。满意值按如下的方式
得到:
1.如果第i行第秒J的同学选择了文科,则他将获得art[i][j]的满意值,如
果选择理科,将得到science[i][j]的满意值。
2.如果第i行第J列的同学选择了文科,并且他相邻(两个格子相邻当且
仅当它们拥有一条相同的边)的同学全部选择了文科,则他会更开
心,所以会增加same_art[i][j]的满意值。
3.如果第i行第j列的同学选择了理科,并且他相邻的同学全部选择了理
科,则增加same_science[i]j[]的满意值。
小P想知道,大家应该如何选择,才能使所有人的满意值之和最大。请
告诉他这个最大值。
Input

第一行为两个正整数:n,m
接下来n术m个整数,表示art[i][j];
接下来n术m个整数.表示science[i][j];
接下来n术m个整数,表示same_art[i][j];
Output

输出为一个整数,表示最大的满意值之和
Sample Input

3 4

13 2 4 13

7 13 8 12

18 17 0 5

8 13 15 4

11 3 8 11

11 18 6 5

1 2 3 4

4 2 3 2

3 1 0 4

3 2 3 2

0 2 2 1

0 2 4 4
Sample Output

152
HINT

样例说明

1表示选择文科,0表示选择理科,方案如下:

1 0 0 1

0 1 0 0

1 0 0 0

N,M<=100,读入数据均<=500

最小割。

对于这种两个中选一个求最优解的就想到最小割了。

先把答案赋值为所有读入数字之和。

每个人向源点连文科的边,向汇点连理科的边,割掉哪边表示不选哪科。

然后再对每个人分别建一个“文科点”和“理科点”。

源点连向“文科点”,“文科点”连向本人和周围的人(infinf),只要有一个人选了理科,这条路就联通了,需要割掉。

“理科点”同理。

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <queue>
#define M 50005
#define inf 0x3f3f3f3f
using namespace std;
int fx[10][5];
int tot,n,m,cur[M],h[M],d[M],v[M],s,t;
struct edge
{int from,to,cap,flow,ne;
}E[M*10];
int C(int x,int y)
{return (x-1)*m+y;
}
int ok(int x,int y)
{if (x>0&&y>0&&x<=n&&y<=m) return 1;return 0;
}
void Addedge(int from,int to,int cap)
{E[++tot]=(edge){from,to,cap,0,h[from]};h[from]=tot;E[++tot]=(edge){to,from,0,0,h[to]};h[to]=tot;
}
int bfs()
{for (int i=s;i<=t;i++)v[i]=0;d[s]=0;queue<int> q;q.push(s),v[s]=1;while (!q.empty()){int x=q.front();q.pop();for (int i=h[x];i;i=E[i].ne){edge e=E[i];if (!v[e.to]&&e.cap>e.flow){q.push(e.to);v[e.to]=1;d[e.to]=d[x]+1;}}}return v[t];
}
int dfs(int x,int a)
{if (x==t||!a) return a;int flow=0;for (int i=h[x];i;i=E[i].ne){edge &e=E[i];if (d[e.to]!=d[x]+1) continue;int f=dfs(e.to,min(a,e.cap-e.flow));if (f>0){flow+=f;a-=f;e.flow+=f;E[i^1].flow-=f;if (!a) break; }}return flow;
}
int dinic()
{int flow=0;while (bfs()){for (int i=s;i<=t;i++)cur[i]=h[i];flow+=dfs(s,inf);}return flow;
}
int main()
{tot=1;scanf("%d%d",&n,&m);int tot=0;s=0,t=n*m*3+1;for (int i=1;i<=n;i++)for (int j=1;j<=m;j++){int x;scanf("%d",&x);Addedge(s,C(i,j),x);tot+=x;}for (int i=1;i<=n;i++)for (int j=1;j<=m;j++){int x;scanf("%d",&x);Addedge(C(i,j),t,x);tot+=x;}fx[1][1]=fx[2][1]=0,fx[1][2]=1,fx[2][2]=-1;fx[3][2]=fx[4][2]=0,fx[3][1]=1,fx[4][1]=-1;fx[5][1]=fx[5][2]=0;for (int i=1;i<=n;i++)for (int j=1;j<=m;j++){int x;scanf("%d",&x);tot+=x;Addedge(s,n*m+C(i,j),x);for (int k=1;k<=5;k++){int nx=i+fx[k][1],ny=j+fx[k][2];if (ok(nx,ny)) Addedge(n*m+C(i,j),C(nx,ny),inf);}}for (int i=1;i<=n;i++)for (int j=1;j<=m;j++){int x;scanf("%d",&x);tot+=x;Addedge(2*n*m+C(i,j),t,x);for (int k=1;k<=5;k++){int nx=i+fx[k][1],ny=j+fx[k][2];if (ok(nx,ny)) Addedge(C(nx,ny),2*n*m+C(i,j),inf);}}cout<<tot-dinic()<<endl;return 0;
}

一开始忘记向本人连边了。。

【BZOJ 3894】 文理分科相关推荐

  1. [BZOJ 3894]文理分科

    3438: 小M的作物 Time Limit: 10 Sec  Memory Limit: 256 MB Submit: 729  Solved: 328 [Submit][Status][Discu ...

  2. [BZOJ 3894]文理分科(最小割)

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

  3. bzoj 3894: 文理分科 最小割

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

  4. bzoj 3894: 文理分科

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

  5. BZOJ 3894 文理分科

    题解:最小割建模 如果某些元素在一起会得到收益考虑最小割 答案 总收益-最小割 注意:对0点的处理 一开始模型是错的 #include<iostream> #include<cstd ...

  6. BZOJ 3894 文理分科 最小割

    题目大意:给定一个m*n的矩阵,每个格子的人可以学文或者学理,学文和学理各有一个满意度,如果以某人为中心的十字内所有人都学文或者学理还会得到一个额外满意度,求最大满意度之和 令S集为学文,T集为学理 ...

  7. BZOJ:3894: 文理分科(网络流)

    题目 每个同学都只能选择文科或者理科一种,选择文科会获得一个权值,理科也有,如果一个人以及周围四个人都选择了一个学科,那么又会获得一个权值. 将权值最大化. 分析 很经典的网络流题目,用最小割. 首先 ...

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

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

  9. 文理分科 (最小割问题)

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

最新文章

  1. npm 卸载_GitHub 收购 npm:天下开源是一家,有个爸爸叫微软
  2. Fastdfs-企业级分布式存储应用
  3. go 接收 ffmpeg avpacket
  4. boost::type_erasure模块Associated types相关的测试程序
  5. java中redis存储map集合_使用RedisTemplate存储Map集合的一点注意
  6. python 类的使用基础
  7. JAVA day03 数组,方法
  8. CVTE 2016 春季实习校招一面(C++后台)
  9. e7用什么主板_主板当中的纽扣电池有什么用?电池没电了会怎样?
  10. hive sql alter table 修改表操作小记
  11. Mac电脑浏览器无法上网
  12. php 正方,php 模拟登陆正方教务系统
  13. Reactive简介
  14. jetson-nano环境查询
  15. 运维实操——日志分析系统ELK(中)之logstash采集数据、伪装rsyslog、多行过滤、grok切片
  16. 收编娘内幕整合版(高质量PDF版)
  17. 中学计算机教材,人教版初中信息技术教材梳理
  18. 华为官微 鸿蒙,华为鸿蒙官微一条微博都没发就火了
  19. 江西理工大学南昌校区排名赛 F: 单身狗的骑马游戏
  20. 2021-09-16什么是MQL4、MQL5语言?

热门文章

  1. Python实现股票双龙战法核心逻辑
  2. 省市区三级联动(带经纬度、离线地图)
  3. 如何在 SAP 轻松访问屏幕上以不同的布局创建不同的启动板
  4. [PMZL]第1卷-误入天庭-01
  5. 智能名片识别系统源码
  6. c# 二进制文件编程实践
  7. python读取包含层级关系的excel
  8. 机器学习之中文处理:文言文还是白话文
  9. java国际化之时区问题处理
  10. 扔掉塑料手环吧!有多高科技不重要,美才是重点