二分图独立集

定理: 二分图最大独立集=n - 二分图最大匹配

其实二分图独立集是特殊的一种最大权闭合子图。我们根据上文“收益”的思想,把选某个点的收益看为1,左部节点为正权点,右部节点为负权点.按照最大权闭合子图的方式建图,答案为正权和-最小割=n-最小割=n-最大流。我们发现把最大权闭合子图中INF的边换成1也不影响答案,因为图中其他边的容量都为1。这样图就变成了二分图匹配中的图,最大流=二分图最大匹配


方格取数

题目大意:

现在就是每个方格里面都有一个数值,但是你选了一个方格之后,它上下左右的都不能选了问你现在取出的数最大的和是多少?


解题思路:

  1. 现在就是我们要求和最大,那么就是冲突的数字要最小,那么我们把冲突这种关系表现为图的联通性的时候那么我们就可以用最小割去求解,就是假如这有两个数是冲突了,在图中就是他们同时存在的时候图是联通的!!

  2. 那么我们观察一下点就是上下左右的点:我们对棋盘进行黑白染色((横坐标+纵坐标)%2==1的点设为黑点),可以发现,若取一个黑格的点,受到影响的就是周围的白点。

  3. 然后可以发现这是一个最小割的套路题,假设所有的点都取,然后去掉最小割,就是答案了。
    建模:S->黑点,容量为点权
    白点->T,容量为点权
    每一个黑点->取该黑点会受到影响的白点,容量为inf
    然后就可以了


代码:

#include <bits/stdc++.h>
#define mid ((l + r) >> 1)
#define Lson rt << 1, l , mid
#define Rson rt << 1|1, mid + 1, r
#define ms(a,al) memset(a,al,sizeof(a))
#define log2(a) log(a)/log(2)
#define lowbit(x) ((-x) & x)
#define IOS std::ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define INF 0x3f3f3f3f
#define LLF 0x3f3f3f3f3f3f3f3f
#define f first
#define s second
#define endl '\n'
using namespace std;
const int N = 2e6 + 10, mod = 1e9 + 9;
const int maxn = 500010;
const long double eps = 1e-5;
const int EPS = 500 * 500;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PII;
typedef pair<ll,ll> PLL;
typedef pair<double,double> PDD;
template<typename T> void read(T &x) {x = 0;char ch = getchar();ll f = 1;while(!isdigit(ch)){if(ch == '-')f*=-1;ch=getchar();}while(isdigit(ch)){x = x*10+ch-48;ch=getchar();}x*=f;
}
template<typename T, typename... Args> void read(T &first, Args& ... args)  {read(first);read(args...);
}
struct node {int to, next, len;
}e[maxn];
int head[maxn], cnt;
int n, m, s, t;
inline void add(int from, int to, int len) {e[cnt] = {to,head[from],len};head[from] = cnt ++;
}int d[maxn],cur[maxn];
int pre[maxn], flow[maxn];bool bfs() {ms(d,0);queue<int> q;q.push(s); d[s] = 1;while(!q.empty()) {int u = q.front(); q.pop();for(int i = head[u]; ~i; i = e[i].next) {int v = e[i].to;if(d[v] || e[i].len <= 0) continue;q.push(v);d[v] = d[u] + 1;}}      for(int i = 0; i <= n; ++ i) cur[i] = head[i];return d[t] != 0;
}int dfs(int u, int flow) {if(u == t) return flow;for(int &i = cur[u]; ~i; i = e[i].next) {int v = e[i].to;if(d[u] + 1 != d[v] || e[i].len <= 0) continue;int delta = dfs(v,min(flow,e[i].len));if(delta <= 0) continue;e[i].len -= delta;e[i^1].len += delta;return delta;}return 0;
}int get_maxflow() {int maxFlow = 0, delta;while(bfs())//bfs进行构建最短路网络while(delta = dfs(s,INF))maxFlow += delta;return maxFlow;
}
int Tn, Tm;
int nx[] = {-1,0,1,0};
int ny[] = {0,1,0,-1};
int sum = 0;
int main() {IOS;ms(head,-1);cin >> Tm >> Tn;s = 0, t = Tm * Tn + 1;n = t;for(int i = 1; i <= Tm; ++ i) {for(int j = 1; j <= Tn; ++ j) {int x;cin >> x;sum += x;if((i + j) & 1) add(s,(i-1)*Tn+j,x), add((i-1)*Tn+j,s,0);else add((i-1)*Tn+j,t,x), add(t,(i-1)*Tn+j,0);}}for(int i = 1; i <= Tm; ++ i) {for(int j = 1; j <= Tn; ++ j) {if((i + j) & 1) {for(int k = 0; k <= 3; ++ k) {int ni = i + nx[k];int nj = j + ny[k];if(ni < 1 || nj < 1 || ni > Tm || nj > Tn) continue;add((i-1)*Tn+j,(ni-1)*Tn+nj,INF);add((ni-1)*Tn+nj,(i-1)*Tn+j,0);}} }}cout << sum - get_maxflow();return 0;
}

骑士共存


代码:

#include <bits/stdc++.h>
#define mid ((l + r) >> 1)
#define Lson rt << 1, l , mid
#define Rson rt << 1|1, mid + 1, r
#define ms(a,al) memset(a,al,sizeof(a))
#define log2(a) log(a)/log(2)
#define lowbit(x) ((-x) & x)
#define IOS std::ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define INF 0x3f3f3f3f
#define LLF 0x3f3f3f3f3f3f3f3f
#define f first
#define s second
#define endl '\n'
using namespace std;
const int N = 2e6 + 10, mod = 1e9 + 9;
const int maxn = 500010;
const long double eps = 1e-5;
const int EPS = 500 * 500;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PII;
typedef pair<ll,ll> PLL;
typedef pair<double,double> PDD;
template<typename T> void read(T &x) {x = 0;char ch = getchar();ll f = 1;while(!isdigit(ch)){if(ch == '-')f*=-1;ch=getchar();}while(isdigit(ch)){x = x*10+ch-48;ch=getchar();}x*=f;
}
template<typename T, typename... Args> void read(T &first, Args& ... args)  {read(first);read(args...);
}
struct node {int to, next, len;
}e[maxn];
int head[maxn], cnt;
int n, m, s, t;
inline void add(int from, int to, int len) {e[cnt] = {to,head[from],len};head[from] = cnt ++;
}int d[maxn],cur[maxn];
int pre[maxn], flow[maxn];bool bfs() {ms(d,0);queue<int> q;q.push(s); d[s] = 1;while(!q.empty()) {int u = q.front(); q.pop();for(int i = head[u]; ~i; i = e[i].next) {int v = e[i].to;if(d[v] || e[i].len <= 0) continue;q.push(v);d[v] = d[u] + 1;}}      for(int i = 0; i <= n; ++ i) cur[i] = head[i];return d[t] != 0;
}int dfs(int u, int flow) {if(u == t) return flow;for(int &i = cur[u]; ~i; i = e[i].next) {int v = e[i].to;if(d[u] + 1 != d[v] || e[i].len <= 0) continue;int delta = dfs(v,min(flow,e[i].len));if(delta <= 0) continue;e[i].len -= delta;e[i^1].len += delta;return delta;}return 0;
}int get_maxflow() {int maxFlow = 0, delta;while(bfs())//bfs进行构建最短路网络while(delta = dfs(s,INF))maxFlow += delta;return maxFlow;
}
int Tn, Tm;
int Map[202][202];
int nx[] = {2,2,-2,-2,-1,-1,1,1};
int ny[] = {-1,1,-1,1,2,-2,2,-2};
int sum = 0;
int main() {IOS;ms(head,-1);cin >> Tn >> Tm;for(int i = 1; i <= Tm; ++ i) {int x, y;cin >> x >> y;Map[x][y] = 1;}s = 0, t = Tn * Tn + 1;n = t;for(int i = 1; i <= Tn; ++ i) {for(int j = 1; j <= Tn; ++ j) {if(Map[i][j]) continue;if((i+j)&1) add(s,(i-1)*Tn+j,1), add((i-1)*Tn+j,s,0);else add((i-1)*Tn+j,t,1), add(t,(i-1)*Tn+j,0);}}int sum = Tn * Tn;for(int i = 1; i <= Tn; ++ i) {for(int j = 1; j <= Tn; ++ j) {if((i+j)&1 && !Map[i][j]) {for(int k = 0; k < 8; ++ k) {int ni = i + nx[k];int nj = j + ny[k];if(Map[ni][nj] || ni < 1 || nj < 1 || ni > Tn || nj > Tn) continue;add((i-1)*Tn+j,(ni-1)*Tn+nj,INF);add((ni-1)*Tn+nj,(i-1)*Tn+j,0);}}}}cout << sum - get_maxflow() - Tm;return 0;
}

最小割 ---- 二分图最大独立集(集合冲突模型) ---- 骑士共存 方格取数(网络流24题)相关推荐

  1. 最小割 ---- 集合冲突模型 ----- P1646 [国家集训队]happiness

    题面: 高一一班的座位表是个n*m的矩阵,经过一个学期的相处,每个同学和前后左右相邻的同学互相成为了好朋友.这学期要分文理科了,每个同学对于选择文科与理科有着自己的喜悦值,而一对好朋友如果能同时选文科 ...

  2. 最小割 ---- 集合冲突模型 ---- AGC038 F - Two Permutations[详解]

    题目链接 题目大意: 给出两个排列P,QP,QP,Q.要求构造两个排列A,B.A,B.A,B. 要求:AiAiAi要么等于iii,要么等于PiPiPi;BiBiBi要么等于iii,要么等于QiQiQi ...

  3. 最小割 ---- 集合冲突模型

    集合冲突模型 1.问题形式 有 n 个物品和两个集合 S,T.将一个物品放入 S 集合会花费 ai,放入 T 集合会花费 bi.还有若干个形如 u,v,w 限制条件,表示如果 u 和 v 同时不在一个 ...

  4. 【网络流24题】I、 方格取数问题(二分图的最大独立集/最小割)

    I. 方格取数问题(二分图的最大独立集/最小割) [问题分析] 二分图点权最大独立集,转化为最小割模型,从而用最大流解决. [建模方法] 首先把棋盘黑白染色,使相邻格子颜色不同,所有黑色格子看做二分图 ...

  5. 734. [网络流24题] 方格取数问题 二分图点权最大独立集/最小割/最大流

    «问题描述: 在一个有m*n 个方格的棋盘中,每个方格中有一个正整数.现要从方格中取数,使任 意2 个数所在方格没有公共边,且取出的数的总和最大.试设计一个满足要求的取数算法. «编程任务: 对于给定 ...

  6. hdu 3657 最大点权独立集变形(方格取数的变形最小割,对于最小割建图很好的题)...

    转载:http://blog.csdn.net/cold__v__moon/article/details/7924269 /* 这道题和方格取数2相似,是在方格取数2的基础上的变形.方格取数2解法: ...

  7. 【BZOJ1475】方格取数 [最小割]

    方格取数 Time Limit: 5 Sec  Memory Limit: 64 MB [Submit][Status][Discuss] Description 在一个n*n的方格里,每个格子里都有 ...

  8. BZOJ 1324: Exca王者之剑/BZOJ 1475: 方格取数 最大权独立集 最小割

    1324: Exca王者之剑 Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 618  Solved: 310 [Submit][Status][Di ...

  9. HDU-1569 方格取数(2) 最小割最大流

    题义很简单,还记得方格取数(1)的时候,使用状态压缩写的,这里由于行列数太大,因此无法进行压缩.所以要运用的最小割最大流的思想来解这道题. 大概是这样分析的,题义是要我们求在一个方格内取出N个点,使得 ...

最新文章

  1. 蚁群:微型机器人的社区
  2. 编写线程安全的Java缓存读写机制 (原创)
  3. [Swift]LeetCode210. 课程表 II | Course Schedule II
  4. 技术系列课|从NE264到NE265:视频编码技术缔造美好生活
  5. python 快速删除程序_如何快速一次性卸载所有python包(第三方库)呢
  6. 西农 生成树配置_华为交换机配置STP功能示例
  7. Kano模型在用户调研中的应用——CRM工具调研实例
  8. python 装饰器,登录小练习
  9. 想不明白:为什么龙芯取消了MIPS版OpenJDK8开源
  10. Java基础知识笔记整理(零基础学Java)
  11. swiftyjson_是时候放弃SwiftyJSON了
  12. 什么是云?云里雾里——最流行的云时代
  13. get与post的区别
  14. 为什么大多数程序员没有工程思维
  15. pytorch、torch、torchvision介绍
  16. 零基础选择前端还是后端?
  17. Packet Tracer - 配置 EtherChannel
  18. 莫比乌斯函数的两种求法(基于欧拉筛、埃氏筛)
  19. struts2《轻量级框架应用与开发--S2SH》笔记
  20. python热图_Python-Seaborn热图绘制的实现方法

热门文章

  1. MySQL数据库分组和聚合函数组合使用
  2. Self-Attention 加速方法一览:ISSA、CCNet、CGNL、Linformer
  3. 什么是 Canny 边缘检测算法?
  4. 基于机器视觉的缺陷检测的原理与方法
  5. 【OpenCV 4开发详解】方框滤波
  6. [Math]理解卡尔曼滤波器 (Understanding Kalman Filter)
  7. windows下搭建hadoop-2.6.0本地idea开发环境
  8. Google 开发新的开源系统 Fuchsia
  9. springMVC4(9)属性编辑器剖析入参类型转换原理
  10. Ctrl+C提示是否终止shell脚本