【bzoj3894】文理分科 网络流最小割
原文地址:http://www.cnblogs.com/GXZlegend
题目描述
输入
输出
样例输入
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
样例输出
152
题解
网络流最小割,和 bzoj3438 差不多。
具体做法:
1.S向每个学生连边,容量为理科收益;每个学生向T连边,容量为文科收益。
2.将每个学生组合拆成两个,S与第一个连边,容量为全理科收益,第一个向组合中学生连边,容量为inf;
组合中学生向第二个连边,容量为inf,第二个向T连边,容量为全文科收益。
3.跑最小割,答案为总收益-mincut。
#include <cstdio>
#include <cstring>
#include <queue>
#define inf 0x3fffffff
using namespace std;
queue<int> q;
int head[40000] , to[300000] , val[300000] , next[300000] , cnt = 1 , s , t , dis[40000];
void add(int x , int y , int z)
{
to[++cnt] = y , val[cnt] = z , next[cnt] = head[x] , head[x] = cnt;
to[++cnt] = x , val[cnt] = 0 , next[cnt] = head[y] , head[y] = cnt;
}
bool bfs()
{
int x , i;
while(!q.empty()) q.pop();
memset(dis , 0 , sizeof(dis));
dis[s] = 1 , q.push(s);
while(!q.empty())
{
x = q.front() , q.pop();
for(i = head[x] ; i ; i = next[i])
{
if(val[i] && !dis[to[i]])
{
dis[to[i]] = dis[x] + 1;
if(to[i] == t) return 1;
q.push(to[i]);
}
}
}
return 0;
}
int dinic(int x , int low)
{
if(x == t) return low;
int temp = low , i , k;
for(i = head[x] ; i ; i = next[i])
{
if(val[i] && dis[to[i]] == dis[x] + 1)
{
k = dinic(to[i] , min(temp , val[i]));
if(!k) dis[to[i]] = 0;
val[i] -= k , val[i ^ 1] += k;
if(!(temp -= k)) break;
}
}
return low - temp;
}
int main()
{
int n , m , i , x , ans = 0;
scanf("%d%d" , &n , &m);
s = 0 , t = 3 * n * m + 1;
for(i = 1 ; i <= n * m ; i ++ ) scanf("%d" , &x) , add(s , i , x) , ans += x;
for(i = 1 ; i <= n * m ; i ++ ) scanf("%d" , &x) , add(i , t , x) , ans += x;
for(i = 1 ; i <= n * m ; i ++ )
{
scanf("%d" , &x) , add(s , i + n * m , x) , add(i + n * m , i , inf) , ans += x;
if(i % m != 0) add(i + n * m , i + 1 , inf);
if(i % m != 1) add(i + n * m , i - 1 , inf);
if(i > m) add(i + n * m , i - m , inf);
if(i <= (n - 1) * m) add(i + n * m , i + m , inf);
}
for(i = 1 ; i <= n * m ; i ++ )
{
scanf("%d" , &x) , add(i + 2 * n * m , t , x) , add(i , i + 2 * n * m , inf) , ans += x;
if(i % m != 0) add(i + 1 , i + 2 * n * m , inf);
if(i % m != 1) add(i - 1 , i + 2 * n * m , inf);
if(i > m) add(i - m , i + 2 * n * m , inf);
if(i <= (n - 1) * m) add(i + m , i + 2 * n * m , inf);
}
while(bfs()) ans -= dinic(s , inf);
printf("%d\n" , ans);
return 0;
}
【bzoj3894】文理分科 网络流最小割的更多相关文章
- [Bzoj3894]文理分科(最小割)
Description 文理分科是一件很纠结的事情!(虽然看到这个题目的人肯定都没有纠结过) 小P所在的班级要进行文理分科.他的班级可以用一个n*m的矩阵进行描述,每个格子代表一个同学的座位.每位 ...
- D - 文理分科 (网络流->最小割)
题目链接:https://cn.vjudge.net/contest/281959#problem/D 题目大意:中文题目 具体思路:我们需要求出最大的满意值,从另一方面想,我们可以求出总的满意值,然 ...
- 【BZOJ3894】文理分科(最小割)
[BZOJ3894]文理分科(最小割) 题面 BZOJ Description 文理分科是一件很纠结的事情!(虽然看到这个题目的人肯定都没有纠 结过) 小P所在的班级要进行文理分科.他的班级可以用一个 ...
- BZOJ_3894_文理分科&&BZOJ_2127_happiness_最小割
BZOJ_3894_文理分科_最小割 Description 文理分科是一件很纠结的事情!(虽然看到这个题目的人肯定都没有纠 结过) 小P所在的班级要进行文理分科.他的班级可以用一个n*m的矩阵进 ...
- [BZOJ 3894] 文理分科 【最小割】
题目链接:BZOJ - 3894 题目分析 最小割模型,设定一个点与 S 相连表示选文,与 T 相连表示选理. 那么首先要加上所有可能获得的权值,然后减去最小割,即不能获得的权值. 那么对于每个点,从 ...
- bzoj 3894 文理分科【最小割+dinic】
谁说这道和2127是双倍经验的来着完全不一样啊? 数组开小会TLE!数组开小会TLE!数组开小会TLE! 首先sum统计所有收益 对于当前点\( (i,j) \)考虑,设\( x=(i-1)*m+j ...
- 【题解】 bzoj3894: 文理分科 (网络流/最小割)
bzoj3894,懒得复制题面,戳我戳我 Solution: 首先这是一个网络流,应该还比较好想,主要就是考虑建图了. 我们来分析下题面,因为一个人要么选文科要么选理科,相当于两条流里面割掉一条(怎么 ...
- Bzoj3894 文理分科
Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 667 Solved: 389 Description 文理分科是一件很纠结的事情!(虽然看到这个题 ...
- 【bzoj3774】最优选择 网络流最小割
题目描述 小N手上有一个N*M的方格图,控制某一个点要付出Aij的代价,然后某个点如果被控制了,或者他周围的所有点(上下左右)都被控制了,那么他就算是被选择了的.一个点如果被选择了,那么可以得到Bij ...
随机推荐
- SpringBoot学习7:springboot整合jsp
springboot内部对jsp的支持并不是特别理想,而springboot推荐的视图是Thymeleaf,对于java开发人员来说还是大多数人员喜欢使用jsp 1.创建maven项目,添加pom依赖 ...
- Apache.Tomcat 调用Servlet原理之Class类的反射机制,用orc类解释
有一个兽人类 package com.swift.servlet; public class OrcDemo { private int hp; private int mp; private int ...
- c++标准之IO库
1.面向对象的标准库 2.多种IO标准库工具 istream,提供输入操作 ostream,提供输出操作 cin:读入标准输入的istream对象.全局对象extern std::istream ci ...
- 【学时总结】◆学时·V◆ 逆元法
◆学时·V◆ 逆元法 □算法概述□ 逆元运算是模运算中的一个技巧,一般用于解决模运算的除法问题.模运算对于加.减.乘是有封闭性的,即 (a±b)%m=a%m±b%m,以及 (a×b)%m=a%m×b% ...
- Redis连接工具类
Redis连接工具类 导包 测试一下(junit) package com.test; import org.junit.Test; import redis.clients.jedis.Jedis; ...
- LeetCode979. 在二叉树中分配硬币
问题:979. 在二叉树中分配硬币 给定一个有 N 个结点的二叉树的根结点 root,树中的每个结点上都对应有 node.val 枚硬币,并且总共有 N 枚硬币. 在一次移动中,我们可以选择两个相邻的 ...
- python--re(匹配字符串)
\d 匹配任何十进制数:它相当于类 [0-9]. \D 匹配任何非数字字符:它相当于类 [^0-9]. \s 匹配任何空白字符:它相当于类 [ fv]. \S 匹配任何非空白字符:它相当于类 [^ f ...
- 《Redis设计与实现》- RDB持久化
Redis RDB持久化功能可以将Redis内存中的数据库状态保存到磁盘里面,避免数据意外丢失. 1. 手动生成 RDB 文件 有两个Redis命令可以用于生成RDB文件: SAVE,该命令会阻塞Re ...
- C++继承权限
牢记两句话: 1.三种继承方式不影响子类对父类的访问权限,子类对父类的访问权限取决于父类的访问控制权. 2.三种继承方式是为了控制子类的调用方对父类的访问权限.比如private继承,对于子类的调用方 ...
- B1071 小赌怡情 (15分)
B1071 小赌怡情 (15分) 常言道"小赌怡情".这是一个很简单的小游戏:首先由计算机给出第一个整数:然后玩家下注赌第二个整数将会比第一个数大还是小:玩家下注 t 个筹码后,计 ...