首页 > 其他分享 >网络流与线性规划24题

网络流与线性规划24题

时间:2023-08-06 22:24:22浏览次数:31  
标签:24 dep vis 线性规划 网络 int edges push id

先贴个自己的Dinic板子。

//最大流
const int inf = 0x3f3f3f3f3f3f3f3f;
struct Edge{
	int from, to, cap;
	bool ori;
	Edge(int u, int v, int c, bool o){
		from = u, to = v, cap = c, ori = o;
	}
};
vector<Edge> edges;
vector<int> id[10005];
int add_edge(int u, int v, int w){
	edges.push_back(Edge(u, v, w, 1));
	edges.push_back(Edge(v, u, 0, 0));
	id[u].push_back(edges.size() - 2);
	id[v].push_back(edges.size() - 1);
	return 0;
}
int n, m, s, t, sum;
int dep[10005], inq[10005], cur[10005], vis;
int bfs(){
	memset(dep, 0x3f, sizeof(dep));
	memset(inq, 0, sizeof(vis));
	memset(cur, 0, sizeof(cur));
	dep[s] = 0;
	queue<int> q;
	q.push(s);
	while(!q.empty()){
		int u = q.front();
		q.pop();
		inq[u] = 0;
		for(int i = 0, v; i < id[u].size(); i ++){
			Edge e = edges[id[u][i]];
			v = e.to;
			if(dep[v] > dep[u] + 1 && e.cap){
				dep[v] = dep[u] + 1;
				if(inq[v] == 0){
					q.push(v);
					inq[v] = 1; 
				}
			}
		}
	}
	if(dep[t] != inf) return 1;
	return 0;
}
int maxflow;
int dfs(int u, int flow){
	int rlow = 0;
	if(u == t){
		vis = 1;
		maxflow += flow;
		return flow;
	}
	int used = 0;
	for(int i = cur[u]; i < id[u].size(); i ++){
		cur[u] = i;
		Edge e = edges[id[u][i]];
		int v = e.to;
		if(e.cap && dep[v] == dep[u] + 1){
			if(rlow = dfs(v, min(flow - used, e.cap))){
				used += rlow;
				edges[id[u][i]].cap -= rlow;
				edges[id[u][i] ^ 1].cap += rlow;
				if(used == flow) break;
			}
		}
	}
	return used;
}
int Dinic(){
	while(bfs()){
		vis = 1;
		while(vis == 1){
			vis = 0;
			dfs(s, inf);
		}
	}
	return maxflow;
}
//费用流

const int inf = 0x3f3f3f3f3f3f3f3f;
struct Edge{
	int from, to, cap, cost;
	bool ori;
	Edge(int u, int v, int c, bool o, int cc){
		from = u, to = v, cap = c, ori = o, cost = cc;
	}
};
vector<Edge> edges;
vector<int> id[80005];
int add_edge(int u, int v, int w, int c){
	edges.push_back(Edge(u, v, w, 1, c));
	edges.push_back(Edge(v, u, 0, 0, -c));
	id[u].push_back(edges.size() - 2);
	id[v].push_back(edges.size() - 1);
	return 0;
}
int n, m, s, t, sum;
int dep[80005], cur[80005], vis[80005];
int bfs(){
	memset(dep, 0x3f, sizeof(dep));
	memset(cur, 0, sizeof(cur));
	memset(vis, 0, sizeof(vis));
	dep[s] = 0;
	vis[s] = 1;
	queue<int> q;
	q.push(s);
	while(!q.empty()){
		int u = q.front();
		q.pop();
		vis[u] = 0;
		for(int i = 0, v; i < id[u].size(); i ++){
			Edge e = edges[id[u][i]];
			v = e.to;
			if(dep[v] > dep[u] + e.cost && e.cap){
				dep[v] = dep[u] + e.cost;
				if(vis[v] == 0){
					q.push(v);
					vis[v] = 1; 
				}
			}
		}
	}
	if(dep[t] != inf) return 1;
	return 0;
}
int maxflow, sumcost;
int dfs(int u, int flow){
	int rlow = 0;
//	cout << u << " ";
	if(u == t){
		vis[t] = 1;
		maxflow += flow;
		return flow;
	}
	int used = 0;
	vis[u] = 1;
	for(int i = cur[u]; i < id[u].size(); i ++){
//		cout << 'a';
		cur[u] = i;
		Edge e = edges[id[u][i]];
		int v = e.to;
		if((vis[v] == 0 || v == t) && e.cap && dep[v] == dep[u] + e.cost){
			if(rlow = dfs(v, min(flow - used, e.cap))){
				used += rlow;
				sumcost += rlow * e.cost; 
				edges[id[u][i]].cap -= rlow;
				edges[id[u][i] ^ 1].cap += rlow;
				if(used == flow) break;
			}
		}
	}
	return used;
}
int Dinic(){
	maxflow = 0, sumcost = 0;
	while(bfs()){
		vis[t] = 1;
		while(vis[t] == 1){
			memset(vis, 0, sizeof(vis));
			dfs(s, inf);
//			system("pause");
		}
	}
	return maxflow;
}

P1251 餐巾计划问题

考虑定义 1 流量。如果直接以毛巾作为流量,会导致出现一条使用过的毛巾就从汇点流走了,没法贡献给后面的日子的情况。因此考虑以“毛巾的使用次数”为流量。
那么,对于 1 使用次数,有两种情况:

  1. 这是最后一次使用这条毛巾。
  2. 这条毛巾会往后贡献。

那么我们将这两种情况拆点。第一类点显然直接连汇点,容量为 \(a_i\) 。这条毛巾可能是直接买的或者从前面拿来的。所以先连一条从源点到这个点的费用为 \(p\) 的边代表直接买毛巾,然后把能贡献到它的二类点与这个点连边,费用为洗毛巾的费用即可。因为最后一定会流满所以从源点向二类点连容量为 \(a_i\) 费用为 0 的边。跑 Dinic 即可。

	cin >> N;
	s = 50001, t = 50002;
	for(int i = 1; i <= N; i ++)
		cin >> a[i];
	cin >> p >> m >> f >> n >> f1;
	for(int i = 1; i <= N; i ++)
		add_edge(s, i + N, inf, p);
	for(int i = 1; i <= N; i ++)
		add_edge(i + N, t, a[i], 0);
	for(int i = 1; i <= N; i ++)
		add_edge(s, i, a[i], 0);
	for(int i = 1; i < N; i ++)
		add_edge(i, i + 1, inf, 0);
	for(int i = 1; i <= N - m; i ++)
		add_edge(i, i + m + N, inf, f);
	for(int i = 1; i <= N - n; i ++)
		add_edge(i, i + n + N, inf, f1);
	Dinic();
	cout << sumcost;

P2765 魔术球问题

好玩题。

分类讨论一个数。对于每个数,它有可能单独放在一个柱子上,也有可能跟之前的某个数凑成完全平方数放到一个柱子上。直接从柱子角度考虑困难,那么正难则反。

假设我们找到了答案,设其为 \(Ans\),考虑直接将 \(1\) 到 \(Ans\) 能连起来的数字连有向边,那么最终会形成一张 DAG 。而每根柱子对应了DAG上的一条路径,而此时这张 DAG 上的最小路径覆盖即为柱子数。DAG 上的最小路径覆盖问题为经典网络流问题,那么只用找到 \(Ans\) 满足 DAG 的最小路径覆盖为 \(n\) 且 \(Ans+1\) 的最小路径覆盖大于 \(n\) 即可。暴力的做法即为枚举 \(Ans\),对于每个 \(Ans\) 跑一遍 Dinic 。

这个时候其实可以二分答案一下,但是没必要。根据网络流的性质,更好的方法是每次枚举新的 \(Ans\) 时在原本的残量网络上直接加边跑 Dinic 。时间复杂度不会证明,反正不大(


	s = 8200, t = 8201;
	for(int i = 1; i <= 55; i ++)
		chk[i * i] = 1;
	cin >> N;
	add_edge(s, 1, 1);
	add_edge(4001, t, 1);
	Dinic();
	while(M - maxflow <= N){
		M ++;
		add_edge(s, M, 1);
		add_edge(M + 4000, t, 1);
		for(int i = 1; i < M; i ++){
			if(!chk[i + M]) continue;
			add_edge(i, M + 4000, 1);
		}
		Dinic();
	}

标签:24,dep,vis,线性规划,网络,int,edges,push,id
From: https://www.cnblogs.com/azusidnya/p/17610179.html

相关文章

  • 【算法】网络流初步
    参考资料用最通俗的语言让你学会网络流OI-Wiki网络流算法学习笔记(28):网络流一、概念网络流指的是在一个每条边都有容量的有向图中找到一种方案,使得源点到汇点的流量最大。网络流问题常见的有三类,分别是最大流,费用流和最小割。最大流顾名思义,表示的是在有向图中找到一种......
  • Linux网络服务之SSH服务
    目录SSH服务1.ssh基础2.ssh原理3.实际操作SSH服务1.ssh基础SSH(SecureShell)协议是一种安全通道协议对通信数据进行了加密处理,用于远程管理作用:主要用来实现字符界面的远程登录、远程复制等功能。SSH协议对通信双方的数据传输进行了加密处理,其中包括用户登录时输入的......
  • 2024备考408Week21
    距24考研还有140天。沉迷虚拟世界太久(小说+动漫),企图逃避现实中的种种不顺,如果我的情绪不能调整到始终如一,那我也很难有所大的成就。多接触现实,多在现实中放松,虚拟世界只会让人平白无故盲目。......
  • ubuntu中VMware虚拟机没有网络可能的原因
    有可能是VMware的网络服务未启动(比如注销账户再进入桌面时不会同时打开VMware的网络服务),可以去顶栏右上角点一下看看是不是这么回事。一般来说重启电脑就可以了,不行的话你就得研究怎么手动启动这个服务了。......
  • 网络安全等级保护定级指南
    对象安全保护等级第一级:等级保护对象受到破坏后会对公民,法人和其他组织的合法权益造成一般损害,但不危害国家安全,社会秩序和公共权益第二级:等级保护对象受到破坏后会对公民,法人和其他组织的合法权益造成严重损害,或对社会秩序和公共利益造成危害,但不危害国家安全第三级:等级......
  • 24. 两两交换链表中的节点 【递归】
    给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。输入:head=[1,2,3,4]输出:[2,1,4,3] 思路:递归fromtypingimportOptional#创建链表defcreate_linked_list(lst):ifnotlst:......
  • 4 Linux网络编程
    4Linux网络编程4.1网络结构模式C/S结构:服务器/客户机,即Client-Server(C/S)结构。B/S结构:浏览器/服务器,即Browser/Server(B/S)结构4.2MAC地址、IP地址和端口4.2.1MAC地址MAC地址(MediaAccessControlAddress),在OSI模型中,第三层网络层负责IP地址,第二层数据链路层......
  • 神经网络可视化工具
    目录1.pipinstallonnx2.根据以下脚本把.pt文件转换成.onnx文件3.在网页打开onnx文件进行可视化展示使用onnx工具能可视化的展示神经网络的结构,便于理解和学习。1.pipinstallonnx2.根据以下脚本把.pt文件转换成.onnx文件"""ExportsaYOLOv5*.ptmodeltoONNXandTorc......
  • FCN-全卷积网络-pytorch搭建
    代码摘自:https://github.com/sovit-123/Semantic-Segmentation-using-Fully-Convlutional-Networks预备知识:下载预训练权重,抽取出网络层实例:运行如下代码,自动下载到C:\Users\**\.cache\torch\hub\checkpoints目录下。vgg=models.vgg16(pretrained=True)抽取网络层,vgg.fe......
  • 深度 Q 网络(deep Q network,DQN)原理&实现
    深度Q网络(deepQnetwork,DQN)原理&实现1Q-Learning算法1.1算法过程Q-learning是一种用于解决强化学习问题的无模型算法。强化学习是一种让智能体学习如何在环境中采取行动以最大化某种累积奖励的机器学习方法。在Q-learning中,智能体根据称为Q-values的函数来选择行动。Q-v......