最小割小记

参考博客:最小割浅谈

关于最小割

  1. 常用描述
    表述一:删去若干条边使得源点到汇点不连通,求删边的权值和的最小可能值。
    表述二:将点集分为(S,T)(S,T)(S,T),记所有从SSS中出发到TTT中的边的权值和为c(S,T)c(S,T)c(S,T),求c(S,T)c(S,T)c(S,T)的最小值。

  2. 求最小割
    a. 以权值为容量,该网络最大流的值即为最小割的值
    b. 在残量网络中,从源点出发进行一次增广BFS,即得到一个分割。该分割是一个最小割。

题型1:对求最小割原理的理解

[AHOI2009]最小割

在这里插入图片描述
在这里插入图片描述
摘自此Blog

[SDOI2014]LIS

在这里插入图片描述
在这里插入图片描述
摘自此Blog

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#define re register
#define maxn 1505
#define LL long long
#define inf 999999999
inline int max(int a,int b){return a>b?a:b;}
inline int min(int a,int b){return a<b?a:b;}
inline int read()
{char c=getchar();int x=0;while(c<'0'||c>'9') c=getchar();while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
}
struct node{int a,b,c,rk;}g[maxn];
inline int cmp(node A,node B) {return A.c<B.c;}
struct E{int v,nxt,w,f;}e[maxn*maxn];
int n,num=1,S,T,Test;
int ans[maxn],cnt,id[maxn],vis[maxn];
int d[maxn],dp[maxn],head[maxn],cur[maxn],in[maxn],out[maxn];
inline void add(int x,int y,int z) {e[++num].v=y;e[num].nxt=head[x];head[x]=num;e[num].w=z;}
inline void C(int x,int y,int z) {add(x,y,z),add(y,x,0);}
inline int check(int s,int t)
{std::queue<int> q;memset(vis,0,sizeof(vis));q.push(s);vis[s]=1;while(!q.empty()){int k=q.front();q.pop();if(k==t) return 1;for(re int i=head[k];i;i=e[i].nxt)if(!vis[e[i].v]&&e[i].w>e[i].f) q.push(e[i].v),vis[e[i].v]=1;}return 0;
}
inline int BFS(int s,int t)
{std::queue<int> q;memcpy(cur,head,sizeof(head));memset(d,0,sizeof(d));d[s]=1,q.push(s);while(!q.empty()){int k=q.front();q.pop();for(re int i=head[k];i;i=e[i].nxt)if(!d[e[i].v]&&e[i].w>e[i].f) {d[e[i].v]=d[k]+1;if(e[i].v==t) return 1;q.push(e[i].v);}}return d[t];
}
int dfs(int x,int now,int t)
{if(x==t||!now) return now;int flow=0,ff;for(re int& i=cur[x];i;i=e[i].nxt)if(d[e[i].v]==d[x]+1){ff=dfs(e[i].v,min(now,e[i].w-e[i].f),t);if(ff<=0) continue;now-=ff,flow+=ff;e[i].f+=ff,e[i^1].f-=ff;if(!now) break;}return flow;
}
int main()
{Test=read();while(Test--){n=read();cnt=0;num=1;memset(head,0,sizeof(head));for(re int i=1;i<=n;i++) g[i].a=read(),dp[i]=1;for(re int i=1;i<=n;i++) g[i].b=read(),g[i].rk=i;for(re int i=1;i<=n;i++)for(re int j=1;j<i;j++) if(g[j].a<g[i].a) dp[i]=max(dp[j]+1,dp[i]);int tot=0;for(re int i=1;i<=n;i++) tot=max(tot,dp[i]);//dp求LIS T=0;for(re int i=1;i<=n;i++) in[i]=++T;for(re int i=1;i<=n;i++) out[i]=++T;++T;for(re int i=1;i<=n;i++) C(in[i],out[i],g[i].b),id[i]=num;for(re int i=1;i<=n;i++) if(dp[i]==1) C(S,in[i],inf);for(re int i=1;i<=n;i++) if(dp[i]==tot) C(out[i],T,inf);for(re int i=1;i<=n;i++)for(re int j=1;j<i;j++) if(g[j].a<g[i].a&&dp[j]+1==dp[i]) C(out[j],in[i],inf);tot=0;while(BFS(S,T)) tot+=dfs(S,inf,T);//建图+跑最小割 for(re int i=1;i<=n;i++) g[i].c=read();printf("%d ",tot);std::sort(g+1,g+n+1,cmp);for(re int i=1;i<=n;i++){int k=g[i].rk;if(check(in[k],out[k])) continue;ans[++cnt]=k;while(BFS(T,out[k])) dfs(T,inf,out[k]);while(BFS(in[k],S)) dfs(in[k],inf,S);e[id[k]].w=e[id[k]^1].w=0;e[id[k]].f=e[id[k]^1].f=0;//退流,排除和当前所选边等价的边的影响 }printf("%d\n",cnt);std::sort(ans+1,ans+cnt+1);for(re int i=1;i<=cnt;i++) printf("%d ",ans[i]);putchar(10);}return 0;
}

题型2:最下生成树相关

例题这里有

题型3:对点的分割 转 对边的分割

[HNOI2013] 切糕
在这里插入图片描述

题型4:最小点割集

最小点割集是指:
给出一张有向图(无向图)和两个点S、T,每个点都有一个正数点权,求一个不包含点S、T的权值和最小的点集使得删掉点集中的所有点后,S无法到达T。

求法:
对于这个问题,我们将每一个点拆成两个点,一个为入点,一个为出点,这两个点之间有一条边权为原图中点权的有向边,从入点指向出点。对于原图中的边x→yx\to yxy,我们将其更改为x的出点→y\to yy的入点。在转化完的图上跑最小割就是原图的最小点割集。

题型5:最小割树——求任意两点的最小割

最小割树
在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
int n,m,node[505],dep[505],fa[505][10],mn[505][10];
int cnt,top[505],to[1005],len[1005],nex[1005];
int read()
{int re=0;char ch=getchar();while(!isdigit(ch)) ch=getchar();while(isdigit(ch)) re=(re<<3)+(re<<1)+ch-'0',ch=getchar();return re;
}
void add_edge(int x,int y,int z)
{to[++cnt]=y,len[cnt]=z,nex[cnt]=top[x],top[x]=cnt;to[++cnt]=x,len[cnt]=z,nex[cnt]=top[y],top[y]=cnt;
}
namespace GHT
{int s,t;int tot,cur[505],dep[505],col[505],col_bucket[505];int cnt=1,top[505],to[3005],cap[3005],flow[3005],nex[3005];void add_edge(int x,int y,int z){to[++cnt]=y,cap[cnt]=z,flow[cnt]=0,nex[cnt]=top[x],top[x]=cnt;to[++cnt]=x,cap[cnt]=z,flow[cnt]=0,nex[cnt]=top[y],top[y]=cnt;//注意这里 }bool BFS(){memset(cur,0,sizeof cur);memset(dep,0,sizeof dep);dep[s]=1,cur[s]=top[s];queue<int>Q;Q.push(s);while(!Q.empty()){int now=Q.front();Q.pop();for(int i=top[now];i;i=nex[i])if(!dep[to[i]]&&cap[i]>flow[i]){dep[to[i]]=dep[now]+1;cur[to[i]]=top[to[i]];Q.push(to[i]);}}return dep[t]!=0;}int DFS(int now,int rest){if(now==t) return rest;int re=0;for(int &i=cur[now];i;i=nex[i])if(dep[to[i]]==dep[now]+1&&cap[i]>flow[i]){int lzq=DFS(to[i],min(rest,cap[i]-flow[i]));if(lzq){rest-=lzq,re+=lzq;flow[i]+=lzq,flow[i^1]-=lzq;//注意这里 if(!rest) break;}}return re;}int Dinic(int x,int y){int re=0;s=x,t=y;for(int i=1;i<=cnt;i++) flow[i]=0;while(BFS()) re+=DFS(s,0x3f3f3f3f);return re;}void get_color(int now,int color){col[now]=color;for(int i=top[now];i;i=nex[i])if(cap[i]>flow[i]&&col[to[i]]!=color)//注意这里 get_color(to[i],color);}void build(int l,int r){if(l==r) return ;int x=node[l],y=node[l+1];int cut=Dinic(x,y);get_color(x,++tot);int L=l,R=r;for(int i=l;i<=r;i++)if(col[node[i]]==tot) col_bucket[L++]=node[i];else col_bucket[R--]=node[i];for(int i=l;i<=r;i++) node[i]=col_bucket[i];::add_edge(x,y,cut);build(l,L-1);build(R+1,r);}
}
void dfs(int now)
{for(int i=1;i<=9;i++){fa[now][i]=fa[fa[now][i-1]][i-1];mn[now][i]=min(mn[now][i-1],mn[fa[now][i-1]][i-1]);}for(int i=top[now];i;i=nex[i]){if(to[i]==fa[now][0]) continue;dep[to[i]]=dep[now]+1,fa[to[i]][0]=now,mn[to[i]][0]=len[i];dfs(to[i]);}
}
int getcut(int x,int y)
{int re=INT_MAX;if(dep[x]<dep[y]) swap(x,y);for(int i=9;i>=0;i--) if(dep[fa[x][i]]>=dep[y]) re=min(re,mn[x][i]),x=fa[x][i];if(x==y) return re;for(int i=9;i>=0;i--) if(fa[x][i]!=fa[y][i]) re=min(re,min(mn[x][i],mn[y][i])),x=fa[x][i],y=fa[y][i];return min(re,min(mn[x][0],mn[y][0]));
}
int main()
{n=read(),m=read();while(m--){int x=read(),y=read(),z=read();GHT::add_edge(x,y,z);}for(int i=1;i<=n;i++) node[i]=i;GHT::build(1,n);dep[1]=1;dfs(1);m=read();while(m--){int x=read(),y=read();printf("%d\n",getcut(x,y));}return 0;
}

题型6:最大权闭合子图

闭合子图指的是,对于有向图,我们选择一些点,在这个点集之中,没有一个点的出边指向非此点集中的点,但是可以有其他点的出边指向这个点集之中。所说的最大权闭合子图,就是在这个图的所有闭合子图中点权和最大的。

求法:
建立源点,向每一个点权为正的点连边,边权为该点的权值。建立汇点,向每一个点权为负连边,边权为该点的权值的绝对值。原图中的边进行保留,边权为infinfinf。最大权闭合子图就是所有的点权为正的点权和减去最小割。

在这里插入图片描述
在这里插入图片描述

题型7:划分点集

(u→v,w)(u\to v,w)(uv,w)为一条从uuuvvv,权值为www的边。

基础模型

nnn个点划分到两个集合A,BA,BA,B。给出若干形如 “若…,则有…的代价/贡献” 的条件。问最大贡献/最小代价是多少。

如果题目问的是最小代价,直接按下面方法连边求最小割。
如果题目问的是最大贡献,答案为∑所有可能贡献−最小代价(最小割)\sum 所有可能贡献-最小代价(最小割)()

定义和SSS相连的点划到AAA集合,和TTT相连的点划到BBB集合,那么我们可以按下面的方法处理题目给出的条件:

  1. 条件-表述1:若把iii划到AAA,则要付出bib_ibi的代价;若把iii划到BBB,则要付出aia_iai的代价
    条件-表述2:若把iii划到BBB,则有bib_ibi的贡献;若把iii划到AAA,则有aia_iai的贡献
    方案:(i→T,bi)(i\to T,b_i)(iT,bi),(S→i,ai)(S\to i,a_i)(Si,ai)
  2. 条件-表述1:若点集XXX中有元素划到BBB,则要付出ccc的代价
    条件-表述2:若点集XXX中元素全部划到AAA,则有ccc的贡献
    方案:(S→new,c),∀i∈X(new→i,inf)(S\to new,c),\forall i\in X(new\to i,inf)(Snew,c),iX(newi,inf)
  3. 条件-表述1:若点集XXX中有元素划到AAA,则要付出ddd的代价
    条件-表述2:若点集XXX中元素全部划到BBB,则有ddd的贡献
    方案:∀i∈X(i→new,inf),(new→T,d)\forall i\in X(i\to new,inf),(new\to T,d)iX(inew,inf),(newT,d)
  4. 条件:若点集XXX中有元素划到BBB,点集YYY中有元素划到AAA,则要付出eee的代价
    常见形式:若点iii划到BBB,点jjj划到AAA,则要付出eee的代价
    方案:∀i∈X(new1→i,inf)\forall i\in X(new1\to i,inf)iX(new1i,inf),∀j∈Y(j→new2,inf)\forall j\in Y(j\to new2,inf)jY(jnew2,inf),(new2→new1,e)(new2\to new1,e)(new2new1,e)
  5. 条件:若点集XXX中有元素划到AAA,点集YYY中有元素划到BBB,则要付出fff的代价
    常见形式:若点iii划到AAA,点jjj划到BBB,则要付出fff的代价
    方案:∀i∈X(i→new1,inf)\forall i\in X(i\to new1,inf)iX(inew1,inf),∀j∈Y(new2→j,inf)\forall j\in Y(new2\to j,inf)jY(new2j,inf),(new1→new2,f)(new1\to new2,f)(new1new2,f)

[Shoi2007]Vote 善意的投票

BZOJ3438: 小M的作物

[BZOJ3218]a + b Problem

处理变形问题的trick:黑白染色,翻转源汇

对于“x,yx,yx,y必须划到不同集合” “x,yx,yx,y划到不同集合有ccc的贡献” “x,yx,yx,y划到相同集合有ddd的代价”这样的条件,我们可以连边(x,y)(x,y)(x,y),黑白染色后x,yx,yx,y一定一个是黑点,一个是白点。

如果将其中一种颜色的点进行翻转源汇,即原本应该连向SSS的边连向TTT,原本应该连向TTT的边连向SSS,那么“x,yx,yx,y在不同集合”就变成了“x,yx,yx,y在相同集合”,“x,yx,yx,y在相同集合”就变成了“x,yx,yx,y在不同集合”

BZOJ1324Exca王者之剑&BZOJ1475方格取数——二分图最大独立集

[BZOJ2132]圈地计划——翻转源汇

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/319915.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

斐波那契数列求法

文章目录求斐波那切数列的几个方法&#xff1a;经典做法&#xff1a;递推&#xff1a;动态规划矩阵快速幂原理&#xff1a;代码&#xff1a;例题&#xff1a;模拟过程求斐波那切数列的几个方法&#xff1a; 经典做法&#xff1a; 众所周知&#xff1a;斐波那契数列的定义是f(…

ASP.Net Core2.1中的HttpClientFactory系列一

引言&#xff1a;ASP.NET Core2.1 中出现了一个新的 HttpClientFactory 功能, 它有助于解决开发人员在使用 HttpClient 实例从其应用程序中访问外部 web 资源时可能遇到的一些常见问题。关于HttpClientFactory 到底解决了那些HttpClient的严重问题&#xff0c;下面是我罗列出来…

最大子矩阵(普通和01)

文章目录普通矩阵&#xff08;单个矩阵值为任何数&#xff09;最大子段和扩展到二维情况01矩阵&#xff08;单个矩阵值为0或1&#xff09;代码&#xff1a;普通矩阵&#xff08;单个矩阵值为任何数&#xff09; 例题&#xff1a;POJ 1074 求出其中最大的子矩阵 答案是&#x…

自动化流程开源框架BotSharp

BotSharp是一款为方便构建智能对话机器人平台而开发的开源框架&#xff0c;最大的特点是所有模型算法都是基于.NET Core开发实现&#xff0c;甚至最基本的Penn Treebank分词标准&#xff0c;都重新用C#实现了。在机器学习python占绝对优势的时代算是不可多得的项目。该项目涉及…

积极参与开源项目,促进.NET Core生态社区发展

今天早上在微信群里聊天聊到百度的SDK 已经支持.NET Core, 百度已经在3月份就支持了&#xff0c;想起当时还是我在他们的github上提的issue&#xff1a; https://github.com/Baidu-AIP/dotnet-sdk/issues/3。.NET Core生态社区的发展已经四年多时间&#xff0c;日趋完善&#x…

Service Fabric 与Ocelot 的集成

概要云应用程序通常都需要使用前端网关&#xff0c;为用户、设备或其他应用程序提供同一个入口点。 在 Service Fabric 中&#xff0c;网关可以是任意无状态服务&#xff08;如 ASP.NET Core 应用程序&#xff09; 。本文介绍了如何将Ocelot用作 Service Fabric 应用程序的网关…

图论复习——最短路

知识点 最短路径算法 最短路径树 每个点uuu的父亲为使uuu得到最短距离的前驱节点&#xff0c;若有多个&#xff0c;则取任意一个。 题目 CF449B Jzzhu and Cities Blog CF464E The Classic Problem Blog [XSY3888] 传送门 对每个点uuu&#xff0c;记d(u)d(u)d(u)表示uuu…

T-Dongle-S3开发笔记——创建工程

创建Hello world工程 打开命令面板 方法1&#xff1a;查看->命令面板 方法2&#xff1a;按F1 选择ESP-IDF:展示示例项目 创建helloworld 选择串口 选择芯片 至此可以编译下载运行了 运行后打印的信息显示flash只有2M。但是板子上电flash是W25Q32 4MB的吗 16M-bit

hdu 1576 A/B

文章目录题目&#xff1a;题解&#xff1a;代码&#xff1a;hdu 1576题目&#xff1a; 要求(A/B)%9973&#xff0c;但由于A很大&#xff0c;我们只给出n(nA%9973)(我们给定的A必能被B整除&#xff0c;且gcd(B,9973) 1)。 Input 数据的第一行是一个T&#xff0c;表示有T组数据。…

ASP.NET Core 中断请求了解一下(翻译)

本文所讲方式仅适用于托管在Kestrel Server中的应用。如果托管在IIS和IIS Express上时&#xff0c;ASP.NET Core Module(ANCM)并不会告诉ASP.NET Core在客户端断开连接时中止请求。但可喜的是&#xff0c;ANCM预计在.NET Core 2.2中会完善这一机制。1. 引言假设有一个耗时的Act…

.net core实践系列之短信服务-架构优化

前言通过前面的几篇文章&#xff0c;讲解了一个短信服务的架构设计与实现。然而初始方案并非100%完美的&#xff0c;我们仍可以对该架构做一些优化与调整。同时我也希望通过这篇文章与大家分享一下&#xff0c;我的架构设计理念。源码地址&#xff1a;https://github.com/SkyCh…

游戏 (博弈论)

https://blog.csdn.net/Mys_C_K/article/details/91443390

.NET Core中Object Pool的简单使用

前言复用&#xff0c;是一个重要的话题&#xff0c;也是我们日常开发中经常遇到的&#xff0c;不可避免的问题。举个最为简单&#xff0c;大家最为熟悉的例子&#xff0c;数据库连接池&#xff0c;就是复用数据库连接。那么复用的意义在那里呢&#xff1f;简单来说就是减少不必…

.Net Core应用框架Util介绍(三)

上篇.Net Core应用框架Util介绍&#xff08;二&#xff09;介绍了Util的开发环境&#xff0c;并让你把Demo运行起来。本文将介绍该Demo的前端Angular运行机制以及目录结构。目录结构在VS上打开Util Demo&#xff0c;会看见如下的目录结构。现代前端通常采用VS Code开发&#xf…

Ocelot简易教程(三)之主要特性及路由详解

作者&#xff1a;依乐祝原文地址&#xff1a;https://www.cnblogs.com/yilezhu/p/9664977.html上篇《Ocelot简易教程&#xff08;二&#xff09;之快速开始2》教大家如何快速跑起来一个ocelot实例项目&#xff0c;也只是简单的对Ocelot进行了配置&#xff0c;这篇文章会给大家详…

Poj 3070 Fibonacci

Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 26063 Accepted: 17394文章目录Description题意&#xff1a;题解&#xff1a;代码&#xff1a;Poj 3070 FibonacciDescription In the Fibonacci integer sequence, F0 0, F1 1, and Fn Fn − 1 Fn − 2 for…

生成函数化简技巧

一些重要式子 ∑i0∞xi11−x\sum_{i0}^{\infty}x^i\frac{1}{1-x}∑i0∞​xi1−x1​ 推论&#xff1a; 11−ax∑i0∞aixi\frac{1}{1-ax}\sum_{i0}^{\infty}a^ix^i1−ax1​∑i0∞​aixi 11−xk∑i0∞xik\frac{1}{1-x^k}\sum_{i0}^{\infty}x^{ik}1−xk1​∑i0∞​xik 11−cxk∑i0∞…

.NET西安社区 [拥抱开源,又见 .NET] 活动简报

拥抱开源, 又见 .NET」随着 .NET Core的发布和开源&#xff0c;.NET又重新回到了人们的视野。除了开源、跨平台、高性能以及优秀的语言特性&#xff0c;越来越多的第三方开源库也出现在了Github上——包括ML.NET机器学习、Xamarin移动开发平台、基于Actor模型的分布式框架Orlea…

dotnet core高吞吐Http api服务组件FastHttpApi

简介是dotNet core下基于Beetlex实现的一个高度精简化和高吞吐的HTTP API服务开源组件&#xff0c;它并没有完全实现HTTP SERVER的所有功能&#xff0c;而是只实现了在APP和WEB中提供数据服务最常用两个指令GET/SET&#xff0c;满足在应用实现JSON,PROTOBUF和MSGPACK等基于HTTP…

ASP.NET Core 中的中间件

前言由于是第一次写博客,如果您看到此文章,希望大家抱着找错误、批判的心态来看。 sky!何为中间件?在 ASP.NET Framework 中应该都知道请求管道。可参考&#xff1a;浅谈 ASP.NET 的内部机制 系列&#xff0c;个人感觉超详细。题外话&#xff1a;说到请求管道&#xff0c;就想…