P4313 文理分科

网络其他地方看到的原话:在说这道题之前,让我们先思考一下最小割的性质.最小割就是使得s到t割掉的最小边的容量,割过之后,所有的点要么与s联通,要么与t联通.

这样的性质,即要么与s有关系,要么与t有关系的性质(非黑即白)就是典型的最小割的题目.

网络流的割的意思是把整体的点分为两个部分,一个部分是只与S有关联,另一个部分的点只与T有关联,(因为割过之后不可能有一个点既能够与S连也能够与T连,否则的话还是联通的)所以这题的第一步先把每一个点都与S和T分别相连,含义是对于每一个点而言,这个点都可能分配给S或者分配给T其中的一个点, 那么对应的连边的权值就是分配给对应的类别的时候所获得的收益,那么就是在删除的收益最小的前提下把这些中间的点分为两个部分.

这题还有一个部分是有相邻点之间的关联. **怎么对待呢?**看图得知

这个新的点,向左链接S,权值为这5个点都为文科时候获得的收益(即周围的几个作为选课与自己一致), 向右链接的5个点的边权都为无穷大.接下来分析这个新的点的作用

假设与之链接的5个点都选择文科(那么他们与T的连线都会从右边与T的连接处切断),那么新的点向左的边就能被保留不需要割断.

同理如果要让T能够与这5个点都有关系,那么首先需要把S和这5个点的链接全部切断,然后新链接的点也必须切断,因为如果不切的话S可以通过新的点到达T,仍然不符合割的定义.

不知道有没有讲清楚:


举个例子说明一下新的点的作用,比如,对于黑边的切法是这样的(蓝色×表示切除), 那么图中说明1 2 5选择理科,3 4 6选择文科,那么这样一来7号点就必须被切除,否则S就能通过7 再由1 2 5到达T,不满足网络流割,所以这样之下S-7的边必须会被切掉, 这条边的权值正好是这5个点都选文科时候的额外收益, 因为它们被分在了不同的组,所以这个是收益不存在,能够满足题意.切完之后就彻底被分类了.

那么完整的就是对于每一个坐标的文科和相邻都文科时候的收益都建立额外的点,与 S链接权值为对应的收益,与5个点链接权值为无穷大(这样就却不掉了),理科同理 与T链接和5个点链接.

能够理解网络的割在这个题中的体现就可以了,至于具体的怎么切割网络流的算法会实现的,需要做的就是理解网络流图和这个题中各个条件的关联性.

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1000;
typedef int ll;
const int maxm = 6e5 + 60;
const int inf = 2147483647 / 3;
int cc[5][2] = {{1,0}, {-1, 0}, {0, 1}, {0, -1}, {0,0}};
#define id(i, j) j+m*(i-1)
struct edge {int s, d, next;ll cap;
};
struct graph {edge saveedges[maxm];int savecnt = 0;int head[maxn*maxn];void init() {savecnt = 0;memset(head, -1, sizeof(head));}void adde(int s, int d, ll c) {saveedges[savecnt].s = s;saveedges[savecnt].d = d;saveedges[savecnt].next = head[s];saveedges[savecnt].cap = c;head[s] = savecnt++;swap(s, d);saveedges[savecnt].s = s;saveedges[savecnt].d = d;saveedges[savecnt].next = head[s];//如果有向图,那么反向边流量为0saveedges[savecnt].cap = 0;//如果无向图, 反向便流量与正向一致//saveedges[savecnt].cap = c;head[s] = savecnt++;}
}G;struct isap {private:edge* save_edge;int* head;int depth[maxn*maxn];int depcnt[maxn*maxn];void bfs(int t) {memset(depth, 0, sizeof(depth));memset(depcnt, 0, sizeof(depcnt));queue<int>q;q.push(t);depth[t] = 1;depcnt[1] = 1;while (!q.empty()) {int nowid = q.front(); q.pop();for (int noweid = head[nowid]; noweid != -1; noweid = save_edge[noweid].next) {edge nowe = save_edge[noweid];//如果这条边的终点已经有赋值了,那么就跳过,因为划分层级取每一个点尽可能小的层级if (depth[nowe.d])continue;depth[nowe.d] = depth[nowid] + 1;depcnt[depth[nowe.d]]++;q.push(nowe.d);}}}/*总的点,用于标识最大的合法层级*/ll dfs(int nowpos, ll have, int source, int dest, int N) {if (nowpos == dest) {return have;}//have一直不变,flow是会逐步增加的ll flow = 0;for (int noweid = head[nowpos]; noweid != -1; noweid = save_edge[noweid].next) {edge nowe = save_edge[noweid];//深度不满足或者这条边的流量没有了,那么跳过这条边的处理if (depth[nowe.d] + 1 != depth[nowpos] || nowe.cap == 0)continue;//利用当前的边进行递归ll newflow = dfs(nowe.d, min(have - flow, nowe.cap), source, dest, N);if (newflow) {flow += newflow;save_edge[noweid].cap -= newflow;//用与1异或定位到当前边的反向边save_edge[noweid ^ 1].cap += newflow;}//如果是因为这个点的储存量有限导致不能再从这里向后扩展,那么不改变这个点的层级,直接退出if (have == flow) {return flow;}}//把当前点向后移动,这一个点所在的层级的节点数少1depcnt[depth[nowpos]]--;//如果因为这个点后移导致这个层级断开,那么直接设置无法再增广的条件if (!depcnt[depth[nowpos]])depth[source] = N + 1;//层级+1depth[nowpos]++;//当前层级包括的节点数量+1depcnt[depth[nowpos]]++;return flow;}
public://传入 《图》 结构体,设置用于最大流的前向星的《图》void init(graph& g) {save_edge = g.saveedges;head = g.head;}ll maxflow(int source, int dest, int N) {ll ans = 0;//先反向标记层级bfs(dest);//如果起点的层级能够在最远的范围之内while (depth[source] <= N) {//就进行dfsll newflow = dfs(source, inf, source, dest, N);ans += newflow;}return ans;}
}FLOW;
int n,m;
int saveori[maxn][maxn];
//斜着跳没有记录
int main() {// freopen("in.txt", "r", stdin);G.init();cin>>n>>m;int N = n*m;int S = 0;int T = 3*N+1;int ans = 0;for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){scanf("%d",&saveori[i][j]);ans+=saveori[i][j];G.adde(S, id(i, j), saveori[i][j]);}}for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){scanf("%d",&saveori[i][j]);ans+=saveori[i][j];G.adde(id(i, j), T, saveori[i][j]);}}for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){scanf("%d",&saveori[i][j]);ans+=saveori[i][j];G.adde(S, id(i, j)+N, saveori[i][j]);for(int ccnt = 0;ccnt<5;ccnt++){int i1 = i+cc[ccnt][0];int j1 = j+cc[ccnt][1];if(0<i1 && i1<=n && 0<j1 && j1<=m)G.adde(id(i, j)+N, id(i1, j1), inf);}}}for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){scanf("%d",&saveori[i][j]);ans+=saveori[i][j];G.adde(id(i, j)+2*N, T, saveori[i][j]);for(int ccnt = 0;ccnt<5;ccnt++){int i1 = i+cc[ccnt][0];int j1 = j+cc[ccnt][1];if(0<i1 && i1<=n && 0<j1 && j1<=m)G.adde(id(i1, j1), id(i, j) + N*2, inf);}}}FLOW.init(G);cout << ans - FLOW.maxflow(S, T, T + 1) << endl;
}

不知道是不是说清了

P4313 文理分科 详细理解相关推荐

  1. (最小割)洛谷P4313文理分科

    洛谷P4313文理分科 思路: 一下子就可以想到最小割,先不考虑一起选的情况的话,就是文理二者择其一的选择. SSS向(i,j)(i,j)(i,j)建边,权值为arti,jart_{i,j}arti, ...

  2. BZOJ 3894 Luogu P4313 文理分科 (最小割)

    题目链接: (bzoj) https://www.lydsy.com/JudgeOnline/problem.php?id=3894 (luogu) https://www.luogu.org/pro ...

  3. P4313 文理分科

    HyperlinkHyperlinkHyperlink https://www.luogu.com.cn/problem/P4313 DescriptionDescriptionDescription ...

  4. P4313 文理分科 网络流

    其实也就卡了卡常,,, 先考虑没有same_art和same_science . 起点用art的流量连向每个点,该点再用science的流量连向终点,断开哪边相当于少了哪边收益. 先全部收益加起来,再 ...

  5. luoguP4313 文理分科

    luoguP4313 文理分科 复习完之后做了道典型题目. 这道题条件有点多 我们逐个分析 如果没有\(sameart\)或者\(samescience\)的限制,就是一个裸的最大权闭合子图的问题了 ...

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

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

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

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

  8. BZOJ3894 文理分科

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

  9. LuoguP4313 BZOJ3894 文理分科——最小割

    洛谷:文理分科 传送门 题目描述: 小P所在的班级要进行文理分科.他的班级可以用一个n*m的矩阵进行描述,每个格子代表一个同学的座位.每位同学必须从文科和理科中选择一科.同学们在选择科目的时候会获得一 ...

最新文章

  1. 直播 | ACL 2021论文解读:基于对抗学习的事件抽取预训练模型
  2. Condition总结-CountDownLatch
  3. 深大计算机科学与技术在广东省,广东考生请注意:深圳大学2021年计划本省总招生人数比例超过75%!...
  4. 数据可视化----我在寻找一款类似vfp或是access这样自带可视化风格的数据库或是键盘数据库...
  5. Job 存储和持久化 (第三部分)
  6. 一文读懂 Spring Bean 的生命周期
  7. 应用出海之--AdMob
  8. 武汉大学计算机 韩立,文澜学术系列讲座 第135期 武汉大学经济与管理学院韩立宁老师:“Financial Network and Industry Connectedness”...
  9. java全能速查宝典.chm_Java全能速查宝典
  10. Quasi-Dense Similarity Learning for Multiple Object Tracking(用于多目标跟踪的拟密集相似度学习)
  11. 继Facebook之后,微软正式宣布:全面进军「元宇宙」
  12. 亮紫色晶体meso四(4-氨基苯基)卟啉TAPP/TAPPPt/TAPPCo/TAPPCd/TAPPZn/TAPPPd/TAPPCu/TAPPNi/TAPPFe/TAPPMn金属配合物-齐岳供应
  13. 多系统引导启动盘“完美解决”方案——Ventoy工具
  14. jsonp跨域访问servlet接口获取json数组,并且渲染数据,前后端完整
  15. 企业建站为何会出问题?责任在谁?
  16. matlab 转子振动,MATLAB的转子振动计算代码
  17. 软件测试术语 - 全面质量管理
  18. 如何用Python打造火车票抢票软件?
  19. 阿里云域名购买、认证、解析 腾讯企业邮箱注册、解析
  20. react倒计时组件

热门文章

  1. HuffMan编码C语言实现
  2. 1_22_python基础学习_0518
  3. 八泉峡明星旅游目的地系列推介会即将举行 蒋大为将现身助阵
  4. Set_output_delay怎么使用?
  5. html怎么画正方形的斜线,html – 斜线的样式
  6. nape.dynamics.InteractionGroup
  7. python获取arduino数据可视化_Arduino数据可视化在实验教学中的应用
  8. C++函数模板非类型参数的使用介绍
  9. U盘出现拒绝访问怎么解决
  10. PDF文件怎么编辑,如何删除其中一页