bzoj3894: 文理分科(还是那道最小割)
3894: 文理分科
题目:传送门
感谢波老师没有来D飞我,让我做出了这题...
题解:
这题其实和我做的上一题(bzoj2132)很像,所以就不写题意了。
依然是那最小割...
这题给出了四个利益矩阵,看似比上一题复杂,想了很久,发现其实建图没有我想象的麻烦。
首先复习一下最小割的定义:把原图分为两个不相交的子集(st和ed)
那么这题用最小割来做的话,我们就把st当成文科的子集,ed为理科。
对于任意的一个x点
st到x连一条流量为文科利益的边,x到ed连一条流量为理科利益的边
那么另外两个利益矩阵怎么处理呢?这里我们就要手动建一些新点
对于任意的一个十字,这个十字中的点都是互相影响的,那么我们用一个新点分别连向十字中的所有点,流量为无限,然后st想这个新点连,流量为同选文科的利益
再建一匹新点:
对于任意的一个十字,这个十字中的点都是互相影响的,那么我们把十字中的所有点都想一个新点连边,流量为无限,然后这个新点向ed连,流量为同选理科的利益
原理就YY吧。。。
上代码:
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#define inf 999999999
#define qread(x)x=read();
using namespace std;
inline int read()
{
int f=,x=;char ch;
while(ch<'' || ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>='' && ch<=''){x=x*+ch-'';ch=getchar();}
return f*x;
}
const int dx[]={,-,,,};
const int dy[]={,,,-,};
struct node
{
int x,y,c,next,other;
}a[];int len,last[];
int n,m,st,ed,head,tail;
void ins(int x,int y,int c)
{
int k1,k2;
k1=++len;
a[len].x=x;a[len].y=y;a[len].c=c;
a[len].next=last[x];last[x]=len; k2=++len;
a[len].x=y;a[len].y=x;a[len].c=;
a[len].next=last[y];last[y]=len; a[k1].other=k2;
a[k2].other=k1;
}
int list[],h[];
bool bt_h()
{
memset(h,,sizeof(h));h[st]=;
list[]=st;head=;tail=;
while(head!=tail)
{
int x=list[head];
for(int k=last[x];k;k=a[k].next)
{
int y=a[k].y;
if(h[y]== && a[k].c>)
{
h[y]=h[x]+;
list[tail++]=y;
}
}
head++;
}
if(h[ed]>)return true;
return false;
}
int find_flow(int x,int flow)
{
if(x==ed)return flow;
int s=,t;
for(int k=last[x];k;k=a[k].next)
{
int y=a[k].y;
if(h[y]==h[x]+ && a[k].c> && s<flow)
{
s+=t=find_flow(y,min(a[k].c,flow-s));
a[k].c-=t;a[a[k].other].c+=t;
}
}
if(s==)h[x]=;
return s;
}
int w[][],l[][],sw[][],sl[][];
int d[][];
int main()
{
qread(n);qread(m);
st=n*m*+;ed=st+;
len=;memset(last,,sizeof(last));
int ss=;
for(int i=;i<=n;i++)for(int j=;j<=m;j++)d[i][j]=ss++;
int sum=;
for(int i=;i<=n;i++)for(int j=;j<=m;j++){qread(w[i][j]);ins(st,d[i][j],w[i][j]);sum+=w[i][j];}
for(int i=;i<=n;i++)for(int j=;j<=m;j++){qread(l[i][j]);ins(d[i][j],ed,l[i][j]);sum+=l[i][j];}
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
{
qread(sw[i][j]);
for(int k=;k<=;k++)
if(d[i+dx[k]][j+dy[k]]>)
ins(d[i][j]+n*m,d[i+dx[k]][j+dy[k]],inf);
ins(st,d[i][j]+n*m,sw[i][j]);
sum+=sw[i][j];
}
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
{
qread(sl[i][j]);
for(int k=;k<=;k++)
if(d[i+dx[k]][j+dy[k]]>)
ins(d[i+dx[k]][j+dy[k]],d[i][j]+n*m*,inf);
ins(d[i][j]+n*m*,ed,sl[i][j]);
sum+=sl[i][j];
}
int ans=;
while(bt_h())ans+=find_flow(st,inf);
printf("%d\n",sum-ans);
return ;
}
bzoj3894: 文理分科(还是那道最小割)的更多相关文章
- [bzoj3894]文理分科_网络流_最小割
文理分科 bzoj-3894 题目大意:题目链接. 注释:略. 想法: 这种题也是一种套路. 我们新建一个点表示收益点. 然后把所有的收益都加一起,求最小割表示代价即可. Code: #include ...
- BZOJ3894文理分科——最小割
题目描述 文理分科是一件很纠结的事情!(虽然看到这个题目的人肯定都没有纠 结过) 小P所在的班级要进行文理分科.他的班级可以用一个n*m的矩阵进行 描述,每个格子代表一个同学的座位.每位同学必须从 ...
- [Bzoj3894]文理分科(最小割)
Description 文理分科是一件很纠结的事情!(虽然看到这个题目的人肯定都没有纠结过) 小P所在的班级要进行文理分科.他的班级可以用一个n*m的矩阵进行描述,每个格子代表一个同学的座位.每位 ...
- 【题解】 bzoj3894: 文理分科 (网络流/最小割)
bzoj3894,懒得复制题面,戳我戳我 Solution: 首先这是一个网络流,应该还比较好想,主要就是考虑建图了. 我们来分析下题面,因为一个人要么选文科要么选理科,相当于两条流里面割掉一条(怎么 ...
- Bzoj3894 文理分科
Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 667 Solved: 389 Description 文理分科是一件很纠结的事情!(虽然看到这个题 ...
- [BZOJ3894]文理分科(最小割)
(1) 对每个位置建一个点F1,S向这个点连art[i][j]的边,这个点向T连science[i][j]的边. (2) 对每个位置再建一个点F2,S向这个点连same_art[i][j]的边,这个点 ...
- BZOJ2127/LG1646 happiness 新建点最小割
问题描述 BZOJ2127 LG1646 题解 和文理分科差不多 收益最大 -> 损失最小 -> 最小割 分别新建点表示互相关系就行了 \(\mathrm{Code}\) #include ...
- 【BZOJ3894】文理分科(最小割)
[BZOJ3894]文理分科(最小割) 题面 BZOJ Description 文理分科是一件很纠结的事情!(虽然看到这个题目的人肯定都没有纠 结过) 小P所在的班级要进行文理分科.他的班级可以用一个 ...
- 【bzoj3894】文理分科 网络流最小割
原文地址:http://www.cnblogs.com/GXZlegend 题目描述 文理分科是一件很纠结的事情!(虽然看到这个题目的人肯定都没有纠结过) 小P所在的班级要进行文理分科.他的班级可以用 ...
随机推荐
- Python学习之LeetCode刷题之路——简单题【1、7、9】
1.两数之和 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标. 你可以假设每种输入只会对应一个答案.但是,你不能重复利用这个 ...
- JAVA学习笔记16——线程的创建和启动
Java使用Thread类代表线程,所有的线程对象都必须是Thread类或其子类的实例.每个线程的作用是完成一定的任务,实际上就是执行一段程序流(一段顺序执行的代码).Java使用线程执行体来代表这段 ...
- JAVA基础数组
数组: 数组是一种容器 存储同一类型的一组数据(必须是 类型相同的一组数据) 定义数组的公式:(有两种) 1.静态定义 1)数据类型[ ] 数组名 = {元素1,元素2,元素3,元素4,元素 ...
- ListView常用属性 (2012-01-12 17:20:27)
比较特别的属性,通过设置这样的属性可以做出更加美观的列表.stackFromBottom——设置该属性之后你最新条目就会显示你列表的最下面,值为true和false,如android:stackFro ...
- mysql外键是多个id组成的字符串,查询方法
借鉴:mysql使用instr达到in(字符串)的效果 结论:select * from 表名where INSTR(CONCAT(字符串),CONCAT(表id)) 问题来源:一表中的某字段是另一表 ...
- Gym - 101670G Ice cream samples(CTU Open Contest 2017 尺取法)
题目: To encourage visitors active movement among the attractions, a circular path with ice cream stan ...
- Python学习-while循环练习
1.计算1-100的和 i = 1; total = 0; while i <= 100: total = total + i; i = i + 1; print(total); 2.打印出1- ...
- 文件内容差异对比-python
上次没精力时候,看了下python自动化运维,给print加了颜色,新鲜哒 今天来写写文件对比 step1:引入difflib库(无需安装,python自带) step2:将文件内容按行分割,spli ...
- Java基础学习总结(81)——如何尽可能的减少Java代码中bug
Java编程语言的人气自然无需质疑,从Web应用到Android应用,这款语言已经被广泛用于开发各类应用及代码中的复杂功能. 不过在编写代码时,bug永远是困扰每一位从业者的头号难题.在今天的文章中, ...
- HDU 3784 继续xxx定律 & HDU 2578 Dating with girls(1)
HDU 3784 继续xxx定律 HDU 2578 Dating with girls(1) 做3748之前要先做xxx定律 对于一个数n,如果是偶数,就把n砍掉一半:如果是奇数,把n变成 3*n+ ...