首页 > 其他分享 >网络流与各种建模(I)

网络流与各种建模(I)

时间:2023-02-13 23:58:59浏览次数:40  
标签:各种 int 建模 流量 网络 leq MAXN 例题

网络流与各种建模(I)

网络流基础

这里默认读者学习过网络流和MCMF,这里仅作复习

  • 网络流解决的问题是给一个源点和汇点,每个边有最大流量,最大化从源点放水到汇点的速率。
  • 网络流的时间复杂度是 \(O(nm)\)。对于一些建模可能跑得快一点,也就是跑不满
  • Dinic 的做法是每次先给图 BFS 分层然后跑增广路,每次仅向层数比自身大的点流出。

时间复杂度的证明:不难发现每次 BFS 后的 \(lv[t]\) 必然减少,否则仍然存在一条路径未流完,矛盾。每次增广路是 \(O(m)\) 的,\(lv[t]\leq n\) 所以时间上限是 \(O(nm)\) 的。

  • Dinic 跑二分图最大匹配是 \(O(m\sqrt n)\) 的,快于匈牙利的 \(O(n^3)\)。
  • 我们可以通过跑完 dinic 后的流量变化判断每条边的流量从而构造方案。
  • 使用的 dinic 封装模板(后面的参考代码默认加上该模板)
namespace graph{
const int MAXN=1e5+5;
const int MR=1e6+5;
int las[MAXN],cur[MAXN];
int lv[MAXN],N,s,t;
queue<int> q;
struct edge{
	int u,v,w,ne;
}e[MR];int tot=1;
void init(){
	tot=1;
	for(int i=1;i<=N;i++)
		las[i]=0;
}
void add(int u,int v,int w){
	++tot;
	e[tot].u=u,e[tot].v=v,e[tot].w=w;
	e[tot].ne=las[u],las[u]=tot;
	return;
} 
void Add(int u,int v,int w){
	add(u,v,w);
	add(v,u,0);
}
bool BFS(){
	for(int i=1;i<=N;i++) lv[i]=-1;
	lv[s]=0;q.push(s);
	while(!q.empty()){
		int u=q.front();q.pop();
		for(int i=las[u];i;i=e[i].ne){
			int to=e[i].v,val=e[i].w;
			if(val&&lv[to]==-1){
				lv[to]=lv[u]+1;
				q.push(to);
			}
		}
	}
	return lv[t]!=-1;
}
ll dinic(int u,ll flow){
	if(u==t) return flow;
	ll rmn=flow;
	for(int i=cur[u];i&&rmn;i=e[i].ne){
		cur[u]=i;
		ll to=e[i].v,val=e[i].w;
		if(val>0&&lv[to]==lv[u]+1){
			ll c=dinic(to,min(rmn,val));
			rmn-=c;
			e[i].w-=c;
			e[i^1].w+=c;
		}
	}
	return flow-rmn;
}
ll max_flow(){
	ll ans=0;
	while(BFS()){
		for(int i=1;i<=N;i++)
			cur[i]=las[i];
		ans+=dinic(s,1e18);
	}
	return ans;
}
}
  • MCMF(费用流)解决的问题是在网络流问题的基础上每个边加上费用,最大化速率的同时要最小费用。
  • 解决方法是把 BFS 分层换成 SPFA 费用分层。
  • 时间复杂度是 \(O(nV)\) 的,\(V\) 是费用的和,证明同上。但是远远跑不满
  • 本篇文章使用的封装费用流模板如下:
namespace graph{
const int MAXN=1e5+5;
const int MR=1e6+5;
struct edge{
	int v,w,c,ne;
}e[MR];int cnt=1;
int las[MAXN],cur[MAXN];
int dis[MAXN];bool inq[MAXN],vis[MAXN];
int N,m,s,t;
queue<int> q;
void add(int u,int v,int w,int c){
	++cnt;
	e[cnt].v=v,e[cnt].w=w,e[cnt].c=c;
	e[cnt].ne=las[u],las[u]=cnt;
	return;
}
void Add(int u,int v,int w,int c){
	add(u,v,w,c);
	add(v,u,0,-c);
}
bool SPFA(){
	for(int i=1;i<=n;i++)
		dis[i]=1e9,inq[i]=0;
	dis[s]=0;q.push(s);
	while(!q.empty()){
		int u=q.front();q.pop();inq[u]=0;
		for(int i=las[u];i;i=e[i].ne){
			int v=e[i].v,val=e[i].w,cost=e[i].c;
			if(val&&dis[v]>dis[u]+cost){
				dis[v]=dis[u]+cost;
				if(!inq[v]){
					inq[v]=true;
					q.push(v);
				}
			}
		}
	}
	return dis[t]!=1e9;
}
int dfs(int u,int flow){
	vis[u]=true;
	if(u==t) return flow;
	int rmn=flow;
	for(int i=cur[u];rmn&&i;i=e[i].ne){
		cur[u]=i;
		int v=e[i].v,val=e[i].w,cost=e[i].c;
		if(val&&dis[v]==dis[u]+cost&&!vis[v]){
			int fl=dfs(v,min(val,rmn));
			rmn-=fl;
			e[i].w-=fl;
			e[i^1].w+=fl;
		}
	}
	vis[u]=false;
	return flow-rmn;
}
ll MCMF(){
	ll ans=0,res=0;
	while(SPFA()){
		for(int i=1;i<=n;i++)
			cur[i]=las[i],vis[i]=0;
		ll flow=dfs(s,1e9);
		ans+=flow,res+=flow*dis[t];
	}
	return res;
}
}
  • 网络流最困难的地方是建模,也就是我们要把一个问题换成网络流问题。
  • 对于一些没有思路的题,不妨想想网络流。

一些写容易忘记的点

  • 在写 MCMF 时需要给 dinic 函数设立一个 vis 数组,表示当前点是否在 dinic 搜索中,以防有重复环。

网络流建模

二分图问题

二分图最大匹配问题

  • 求二分图最大匹配。
  • 要求 \(O(\sqrt ne)\)。

网络流的常见建模方式是建立超级源点和超级汇点

在本题中我们建立超级源点 \(s\) 和超级汇点 \(t\)。在原图基础上,\(s\) 连所有左部点,所有右部点连 \(t\)。所有边流量为 \(1\)(这里保证了每个点、边都只会被使用一次)。

二分图最大权完美匹配问题

  • 求二分图最大权完美匹配。没有输 -1
  • \(n\leq 300\)。

在上题的基础上增加费用限制。源点汇点的边费用均为 \(0\),中间边费用给定。跑一遍最大费用。

【例题】路径覆盖问题

  • 给 DAG,求最少的路径覆盖所有点。路径不可重点。
  • \(n\leq10^3\)。

DAG 所提供的条件在于我们可以随便连一个没有入边的节点。

我们把问题转换成二分图最大匹配问题。一个节点拆成两个,一个匹配出边,一个匹配入边。这样答案就是点数减去匹配数。

【习题】P2763 试题库问题

  • \(n\) 个物品,物品有多个标签。
  • 构造,把一些物品分到标签类里面,给定每个标签类 \(i\) 的大小 \(r_i\)。
  • \(n\leq 10^3\),不同标签数 \(\leq 20\)。

【习题】P3254 圆桌问题

【习题】P2765 魔术球问题

  • 有 \(n\) 根柱子,依次进入 \(1,2,\dots m\)。
  • 每个数放的柱子要和当前柱子顶部的数的和是完全平方数。
  • 最大化 \(m\),给构造。
  • \(n\leq 55\)。

【例题】最小链覆盖

  • 给 DAG,求最少的路径覆盖所有点。路径可重点。
  • \(n\leq10^3\)。

传递闭包后跑路径覆盖即可。传递闭包使用 \(\text{bitset}\) 优化做到 \(O(\dfrac{n^3}{\omega})\)。

这道例题可以看做一种偏序关系,定理 \(\text{Dilworth}\) 告诉我们最小链覆盖等于最长反链。举个通俗的例子,最小严格上升子序列覆盖等于最长非严格下降子序列长度。

一些解释:一个 DAG(或偏序集)的反链指最大的点集,点集内两点都不可达。

我们使用 \(\text{Dilworth}\) 定理练习练习。

【例题】P4298 [CTSC2008]祭祀

  • 给 DAG,求反链长度,构造最长反链,问每个点是否可以作为最长反链一点。
  • \(n\leq 100\)。

第一问按照上面来,我们先讲第三问。

对于枚举点 \(i\),我们删掉点 \(i\) 和所有与 \(i\) 有偏序关系的点,如果得到新图的答案恰比原图答案少 \(1\),那么这个点可作为最长反链上一点,否则不行。

第二问我们贪心枚举每一个可以作为最长反链的点,每次选中一个 \(i\) 就把 \(i\) 和和 \(i\) 有偏序关系的点全部删掉就可以了。

给一份参考代码:

#include<iostream>
#include<queue>
using namespace std;
#define ll long long
const int inf=1e9;
namespace graph{/*do sth.*/}
const int MAXN=105;
bool flag[MAXN][MAXN];
int n,m,s,t;
int ls[MAXN],rs[MAXN],tot=0;
bool p1[MAXN],p2[MAXN],chc[MAXN],used[MAXN];
int main(){
	s=graph::s=++tot;
	t=graph::t=++tot;
	cin>>n>>m;
	for(int i=1;i<=n;i++)
		ls[i]=++tot,rs[i]=++tot;
	for(int i=1;i<=m;i++){
		int u,v;cin>>u>>v;
		flag[u][v]=1;
	} 
	for(int k=1;k<=n;k++)
		for(int i=1;i<=n;i++)
			for(int j=1;j<=n;j++)
				if(flag[i][k]&&flag[k][j])
					flag[i][j]=1;//传递闭包 
	graph::N=tot;
	for(int i=1;i<=n;i++)
		graph::Add(s,ls[i],1),
		graph::Add(rs[i],t,1);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			if(flag[i][j])
				graph::Add(ls[i],rs[j],1);
	int ans=n-graph::max_flow();
	cout<<ans<<endl;
	for(int k=1;k<=n;k++){
		int cnt=0;
		graph::init();
		for(int i=1;i<=n;i++)
			if(flag[k][i]||flag[i][k]||k==i)
				p1[i]=1;
			else p1[i]=0;
		for(int i=1;i<=n;i++)
			if(!p1[i])
			cnt++,
			graph::Add(s,ls[i],1),
			graph::Add(rs[i],t,1);
		for(int i=1;i<=n;i++)
			for(int j=1;j<=n;j++)
				if(!p1[i]&&!p1[j]&&flag[i][j])
					graph::Add(ls[i],rs[j],1);
		if(cnt-graph::max_flow()==ans-1)
			chc[k]=1;
	}
	for(int i=1;i<=n;i++)
		if(chc[i]&&!used[i]){
			cout<<"1";
			for(int j=1;j<=n;j++)
				if(flag[i][j]||flag[j][i]||i==j)
					used[j]=1;
		}else cout<<"0";
	cout<<endl;
	for(int i=1;i<=n;i++) cout<<chc[i];
	return 0;
}

【例题】[SCOI2007] 修车

  • \(m\) 个师傅修 \(n\) 个车,每个师傅修每个车有不同的时间 \(T_{i,j}\)。
  • 求所有顾客的最小平均等待时间。
  • \(m\leq 9,n\leq 60\)。

不难发现如果一个车 \(c\) 是当前师傅 \(i\) 倒数第 \(k\) 个维修的,那么它对等待时间的贡献就是 \(T_{i,j}\times k\)。

我们考虑转成二分图,左边代表每一个车,右边代表每个师傅的状态(即师傅 \(i\),倒数第 \(j\) 个维修),中间连带权边表示左边的车给右边状态的师傅修的贡献。那么问题就变成了二分图最大匹配最小权。

跑费用流。

【引理】\(\textbf{Konig}\) 定理

二分图最小点集覆盖等于最大匹配。

解释:二分图最小点集覆盖指选一些点使得每条边都有端点是标记点。

证明是显然的,留给读者。(提示,证明两个不等式,即左小等右,右小等左)。

【例题】UVA11419 SAM I AM

  • 给 \(n\times m\) 的方格,有一些标记点。
  • 选择一些行、列使得每个标记点都在标记行或列上。
  • \(n,m\leq10^3\)。

利用 \(\text{Konig}\) 定理转化成二分图最大匹配。

【引理】最大独立集

二分图最大独立集等于总点数减去最小点覆盖

证明:考虑最大独立集为 \(S\)。考虑每一条边,必然不能都是 \(S\) 点,所以 \(V-S\) 是最小点覆盖。

这些结论在二分图当中有一定作用。

【题型】选择限制问题

  • 给一些元素,每个元素选或不选,选有奖励 \(v_i\)。
  • 给一些限制 \(u,v\) 表示 \(u,v\) 不能都选。
  • * 特殊限制(一般是隐藏条件)限制构成二分图。

一般特殊条件难以注意(可能需要染色),如果注意到了就变成了最大独立集问题。

现在点有了权值,我们可以源点向左部点连边的容量是 \(v_i\),右部点向汇点连边的容量为 \(v_i\),原图边容量为 \(\infty\)。

【习题】P3355 骑士共存问题 黑白染色。

【习题】P5030 长脖子鹿放置 行染色。

利用最小割

【引理】最小割

最小割等于最大流

这里最小割的意思是割去最小边权和的边集使得图不连通。

利用最小割原理,我们可以搞些有趣的建模。

【题型】二者取一问题

  • 给 \(n\) 个选择,答案只有 \(0/1\)。两种选择都有不同的奖励权值。
  • 给 \(m\) 个奖励条件,第 \(i\) 条形如如果一个集合的题全部选择 \(0\)(或者 \(1\))。那么额外获得一定的奖励权值。
  • 最大化奖励权值。

先考虑简单情况,也就是没有奖励的时候,可以建出下面这样的图:

image

我们应该是想要所有边权减去最大流。

所为奖励本质上就是限制。也就是说如果你一个点集没有割完同一方向的边,那么你就要把奖励也给割掉。

也就是说当且仅当你把一边的边全部保留你才能不割奖励,不妨设是限制是全部选 \(0\)。那么可以建图如下:

image

这里我们可以发现无穷边是不能割的,如果你选择保留了 \(1,2,3\) 之一的 \(1\) 选项,那么就会存在 \(s\to q1\to u\to t\) 的路径,此时必须割掉奖励。

全部选 \(0\) 同理。

【习题】P4313 文理分科 二者取一式问题的简单形式。

【习题】P1361 小M的作物 板子。

【题型】最大权闭合子图

  • 定义有向图 \(G\) 的闭合子图 \(G'\) 为 \(G'\) 中的点在 \(G\) 中的出边终点都在 \(G'\) 当中。
  • 每个点有点权(可能为负)求最大权闭合子图。

建模方式是给源点连向所有正权点,所有负权点连向汇点,流量是点权绝对值。原图正常连边,流量为 \(\infty\)。

考虑最小割,割掉正权点表示不选择该点,割掉负权点表示选择该点,最终的答案为所有正权和减去最小割。

下面证明这一建模:考虑每一条路径 $s\xrightarrow{a} u\xrightarrow{\infty} v\xrightarrow{b} t $。有两种割的方式:

  • 割 \(a\) 留 \(b\):表示不选择 \(u\) 也不选择 \(v\)。
  • 留 \(a\) 割 \(b\):表示选择 \(u\) 也选择 \(v\)。

刚好是闭合子图的形式,剩下还有一种形式:

  • 不选 \(u\) 但选 \(v\)

的形式必然不优,证明完毕。

【习题】P3872 [TJOI2010]电影迷

  • 给有向图,点有点权,边有边权。
  • 求极多边子图,最大化点权减边权。
  • \(n\leq 100\),保证边权为正。
  • 提示:如果边权是 \(\infty\) 就可以转化成最大权闭合子图,可以考虑在最大权闭合子图的建模上改造。

【习题】P2762 太空飞行计划问题 二分图上跑最大权闭合子图。

【习题】 UVA1389 Hard Life 最大密度闭合子图。

  • 提示:二分密度 \(\rho\),所有点权减去 \(\rho\) 跑最大权闭合子图,看权是否 \(>0\) 即可。

拆点法

【例题】P1402 酒店之王

  • \(n\) 个人,每个人有自己喜欢的一些饮料和食物。每种饮料和食物只有一份。
  • 合理安排,最大化饮料食物都喜欢的人数。
  • \(n,p,q\leq100\)。

同上面的建模思路,我们分成三部点,左边时饮料,中间是人,右边是食物。超级源点向饮料连,饮料向喜欢的人连,人向食物连,食物向超级汇点连,所有边流量为 \(1\)。

跑网络流发现一个问题,一个人可能同时被多个食物或饮料匹配上,这是因为每个人也是有限制的。

一般来说我们解决点的限制可以拆点转为边的限制

本题中我们每个人开一个副本,饮料连本体,本体连副本,副本连食物即可。大概可以建出来这样的图

image

跑网络流。

【例题】P1345 [USACO5.4]奶牛的电信

  • 给定无向图,问最少删多少点才能使 \(c_1,c_2\) 不连通(不能删 \(c_1,c_2\))。
  • \(n\leq 100,m\leq600\)。

我们在利用最小割的时候要清楚哪些边可以割,哪些边不能割。

本题我们主要是研究点,我们先把点拆称 \(l_u,r_u\),超级源点连向 \(l_u\),\(r_u\) 连向超级汇点。由于需要割点,所以 \(l_u\to r_u\) 连容量为 \(1\) 的边,特别的,若 \(u\in\{c_1,c_2\}\) 那么容量也要设为 \(\infty\)。

对于边 \((u,v)\) 来说他是不能割的,所以对 \(r_u\to l_v,r_v\to l_u\) 都设 \(\infty\) 的容量。

跑网络流。

【习题】P3171 [CQOI2015]网络吞吐量

【习题】P3866 [TJOI2009] 战争游戏

平面图最大流问题

【引入】平面图与对偶图

  • 平面图:存在以同构图 \(G\) 使得任意两边仅在节点处相交。
  • 对偶图:把平面图的面试做点,分割两个面的边试做边的图。

举个栗子,下图中原图 \(G\) 和对偶图 \(G'\) 都是平面图,\(G'\) 是 \(G\) 的对偶图。

image

平面图有个很好的性质,就是平面图的最小割等于对偶图的最短路。

拿上面的图来说,我们要求 \(2,5\) 的最小割,可以建下面这样的对偶图:

image

对偶图有两个外部点,作为起点和终点,是把直线 \(2,5\) 连出来把平面分成两部分而成的。最短路最小性显然。

【例题】P2046 [NOI2010] 海拔

  • 给一个 \(n\times n\) 的网格图,每条边沿南北或东西。你知道每条边两个方向的客流量。
  • 把 \(n\times n\) 个节点黑白染色,要求 \((1,1)\) 染黑,\((n,n)\) 染白。
  • 最小化从黑节点进入白节点的客流量。
  • \(n\leq 500\)。

标准的平面图,显然的是黑白两个色块必然连续,也就是我们必然可以在对偶图上找到一条路径分开 \((1,1),(n,n)\) 且路径上所有边在平面图中所对应的都是黑白边。

下图是一个参考的例子。

image

【习题】P4001 [ICPC-Beijing 2006] 狼抓兔子

给流赋予意义

在上面的例子中,网络流当中的“流”似乎只是一种工具,下面介绍几道把“流”视作为选择等有意义的事物的题目。

【例题】P3980 [NOI2008] 志愿者招募

  • 给你 \(m\) 种段,每种段形如 \([l_i,r_i]\),代价是 \(w_i\)。每种段都有无限个。
  • 选代价最小的段使得每个位置 \(i\) 的段数都不小于 \(a_i\)。
  • 保证有解。
  • \(n\leq10^3,m\leq10^4\)。

我们把“流”看做每个人的选取情况

当你想不到什么好的做法时不如想想万能做法网络流。

本题当中每一个段他都对应一个区间,而且取了一个段就要区间加,这不符合二分图的建图。

我们考虑这事一个 DAG,我们把位置 \(i\) 变成边 \(i\to i+1\),费用应该为 \(0\)。但是这里流量比较奇怪,要的是不小于,我们先放一边,我们应该需要的是费用

每个端 \([l_i,r_i]\) 的建模方式应该是 \(l_i\to r_i+1\),表示跳过一个 \([l_i,r_i]\),流量是 \(\infty\),费用是 \(w_i\)。猜测最终的流量应当是定值 \(c=\infty\)。

我们考虑每个位 \(i\) 来说它必须有 \(a_i\) 个位不经过它,转化一下就变成了最多只能容纳 \(c-a_i\) 个流,这个作为上面的流量即可。

注意,我们这样子建模可能让答案不为 \(c\),需要加上一个超级源点 \(s\to 1\),汇点 \(n+1\to t\)。边权为 \(c\)。

妙妙妙。

【例题】P3358 最长 \(\textbf{k}\) 可重区间集问题

  • 若干开区间,最大化选取的开区间长度之和使得每个位置覆盖区间不超过 \(k\)。
  • \(k\leq n\leq 500\)。

我们把“流”试做为每个线段的选取情况。

先显然的离散化,长度变成权值,假设值域为 \(w\)。

按照上面的套路,我们尝试先建一个长度为 \(w\) 的链表示 \([1,w]\) 每个长度为 \(1\) 的开区间,流量是 \(k\),费用是 \(0\)。

每个给定开区间 \([l,r]\) 给节点 \(l,r\) 连边,流量是 \(1\) 费用是 \(len\)。这样一个流量经过代表选择了这条边,反之亦然。

跑最大费用即可。

【例题】P1251 餐巾计划问题

  • 你要进行 \(n\) 天的营业,第 \(i\) 天会使用 \(r_i\) 的餐巾。
  • 每天结束,你会把用完的餐巾交给快洗店(等待天数 \(d_1\),费用 \(r_1\))或慢洗店(等待天数 \(d_2\),费用 \(r_2\))或留下来等明天。
  • 每天开始你也可以选择以 \(p\) 的价格购入新的餐巾。
  • 最小化价格。
  • \(n\leq 2000\)。

把“流”视为每个餐巾。

每天早上我们要购入一些餐巾,每天早上要向晚上送 \(r_i\) 的餐巾,每天晚上可以给后面 \(d_1,d_2\) 天的早上提供若干餐巾,显然的把每天拆成早上和晚上。

有个小问题,就是发现源点给早上提供的餐巾是 \(\infty\),到了晚上如果流回去某天的早上那么这个流就会经过早晚边两次,这个建图的早晚边是流量瓶颈,这样肯定够不成最大流,换句话说这个模型求出来的最大流是不会换洗的。

这个图的缺点在于流不能从晚上的点流回去早上的点,但是我们发现每个晚上的点需求是固定的 \(r_i\)。我们反过来把晚上的点设为左点,早上的点设为右点,这样每个右点需要给汇点提供 \(r_i\) 流量,左点从源点获得 \(r_i\) 流量,左点流量可以向下传递,右点也可以直接从源点获得 \(\infty\) 流量、费用 \(p\)(购入餐巾),左点 \(i\) 也可以向 \(i+d_j\) 的早晨提供若干费用为 \(v_i\) 的流量(换洗)。建模完成。

int main(){
	int ls[MAXN],rs[MAXN],s,t,val[MAXN],tot=0;
	int n,p,d1,v1,d2,v2;
	cin>>n;
	for(int i=1;i<=n;i++) cin>>val[i];
	cin>>p>>d1>>v1>>d2>>v2;
	s=graph::s=++tot;
	t=graph::t=++tot;
	for(int i=1;i<=n;i++)
		ls[i]=++tot,rs[i]=++tot;
	for(int i=1;i<=n;i++){
		graph::Add(s,ls[i],val[i],0);
		graph::Add(s,rs[i],inf,p);
		graph::Add(rs[i],t,val[i],0);
		if(i+d1<=n) graph::Add(ls[i],rs[i+d1],inf,v1);
		if(i+d2<=n) graph::Add(ls[i],rs[i+d2],inf,v2);
		if(i<n) graph::Add(ls[i],ls[i+1],inf,0);
	}
	graph::N=tot;
	cout<<graph::MCMF();
	return 0;
}

其他的建模方法

【例题】P2754 [CTSC1999]家园 / 星际转移问题

  • 有 \(m\) 个交通工具每一时刻循环经过若干指定站。(不同的站不超过 \(n+2\) 个)
  • 把 \(k\) 个人从站 \(0\) 运送到站 \(-1\) 的最小需要时间。
  • \(n\leq 13,m\leq 20,k\leq 50\)。

对时间分层建模,我们对于每个站的每个时刻状态建模。

枚举需要达成的时刻 \(T\)(这里可以二分,但是没必要),对于一开始站 \(0\) 在 \(0\) 时刻有 \(k\) 点流量,建模不断让他往时刻大的它本身流动,跑最大流即可。

时间不会超过 \(nk\),时间复杂度是 \(O(n^4k^4)\) 远远跑不满。

【习题】P6054 [RC-02] 开门大吉

  • \(n\) 个题,每题 \(m\) 个选项,每个选项有对应奖励值 \(p_{i,j}\)。
  • 若干限制,要求第 \(u_i\) 题比 \(v_i\) 题选择的编号至少多 \(k_i\)。
  • \(n,m,p\leq 80\)。

提示:这里 \(n,m\) 小得可怜,时间、空间却大的离谱。能不能对每一个题目对应选择的状态看做一个点?

【例题】P2045 方格取数加强版

  • 搞 \(k\) 条从 \((1,1)\) 到 \((n,n)\) 的每次只能向右、下的路径。
  • 求经过点权之和最大(经过多次只算一次)。
  • \(n\leq 50\)。

有个难搞的地方叫做经过多次只算一次。我们介绍一个模型我们叫做流量限制模型,如下:

image

这种建模跑最大费用的时候,前 \(w\) 的流量肯定会经过费用为 \(c\) 的边,后面的只能进入费用为 \(0\) 的边,目的达成。

本题中对方格分点即可。

【例题】P3163 [CQOI2014]危桥

  • 给一个双向图,一些边是好边,可以经过无穷次,一些是坏边,只能经过 \(2\) 次。
  • 问:小 A、小 B 分别从 \(s_1,s_2\) 出发,终点在 \(t_1,t_2\) 要分别走 \(k_1,k_2\) 个来回,是否可行。
  • \(n\leq 50\),多测。

建图是显然的,如果是好边则连 \(\infty\) 流量,否则连 \(2\) 流量。本题显然是一个多原、汇网络流。

我们先说结论:

  • 对 \(s_1,s_2\) 作为源点,\(t_1,t_2\) 作为汇点,分别拥有 \(2k_1,2k_2\) 的流量;
  • 对 \(s_1,t_1\) 作为源点,\(s_2,t_2\) 作为汇点,分别拥有 \(2k_1,2k_2\) 的流量。

若以上两图都有 \(2(k_1+k_2)\) 的最大流,那么可行;否则不可行。下面给出证明:

若答案有解,那么程序必然判断有解:这是显然的。

若程序判断有解,那么答案有解:考虑两个跑完的图的使用网络图为 \(W_1,W_2\),那么 \(\dfrac{W_1+W_2}2\) 可以得到 \(s_1\to t_1\) 的流量使用情况,\(\dfrac{W_1-W_2}{2}\) 可以得到 \(s_2\to t_2\) 的流量使用情况。如果情况不合法,也就是有一个边,两个网络的使用情况为 \(d_1,d_2\) 则 \(|d_1|+|d_2|\geq 2\)。这种情况取 \(d_2'\) 和 \(d_1\) 同号,数值与 \(d_2\) 相同,那么 \(|d_1+d'_2|\geq 2\) 也就是上述两种情况中有一种不可取,矛盾。故成立。

总结

这个博客的题目量很大,有时间自己写写题。

弱鸡还不会上下界,等一段时间补上下界,这也是为什么这个博客的标题带 (I)

标签:各种,int,建模,流量,网络,leq,MAXN,例题
From: https://www.cnblogs.com/KawaiiOU/p/17118330.html

相关文章

  • linux010之网络管理
    简介:在实际工作中,项目上会给你一个linux系统,然后再给你一个局域网地址,让你将linux的网络配置到局域网上,方便后续操作。如果在虚拟机上配置网络?在linux的网络配置文......
  • Python 高级编程之网络编程 SocketServer(七)
    目录一、概述二、socket模块与socketserver关系三、socketserver模块使用1)创建TCPServer2)创建UDPServer四、异步服务器类(对线程、多进程)1)ThreadingMixIn(多线程)2)Forki......
  • Matlab用深度学习循环神经网络RNN长短期记忆LSTM进行波形时间序列数据预测|附代码数据
    全文链接:http://tecdat.cn/?p=27279最近我们被客户要求撰写关于循环神经网络RNN的研究报告,包括一些图形和统计输出。此示例说明如何使用长短期记忆(LSTM)网络预测时间......
  • 聊聊VirtualBox中的网络连接方式
    在平时使用虚拟系统需要连接网络时,就需要在虚拟化软件中配置系统的网络连接,其中拿常用的VirtualBox来说,VirtualBox中有以下4种网络连接方式:​BridgedAdapterNATInternalHos......
  • 2023.2.13环保环保监测中心网络新闻发布系统
         2021级《软件工程》课前测试试卷(180分钟) 河北省环保监测中心网络新闻发布系统(卷面成绩40分,占课程过程考核20分) 1、项目需求:河北省环保监测中心网络新闻......
  • 生草——网络流知识点等梳理
    服了,看来只写题解不系统总结的博客并不能十分有效地提高对知识点的理解程度。还是得回归到以前既总结知识本身,又写题解的形态。否则就会落到今天这个下场——知识点大量遗......
  • [Oracle19C ASM管理] ASM的网络服务
    启用了ASM集群以后,网络管理放给了grid用户。grid用户的$ORACLE_HOME/network/admin有网络配置文件,而oracle用户下的网络配置文件则不存在了。[[email protected]......
  • 经典-量子混合二分类网络预测肺炎
    本教程使用MindQuantum复现了论文AClassical-QuantumConvolutionalNeuralNetworkforDetectingPneumoniafromChestRadiographs中的网络结构。准备工作安装MindQ......
  • 基础-Linux网络
    查看路由表[root@localhost~]#route-nDestinationGatewayGenmaskFlagsMetricRefUseIface0.0.0.0172.18.4.2540.0.0.0......
  • 网络
    OSI与TCP/IP模型: 物理层:传输介质:有线、无线、网卡、中继器数据链路层:封装数据 网络层:逻辑地址寻址、路径选择、实现不同网段的通信、连接异构网络......