首页 > 其他分享 >vector最大流试预习

vector最大流试预习

时间:2023-07-18 22:57:19浏览次数:52  
标签:205 int cb 预习 vector 流试 mp size

最大流预习

目录

前情提要:

看看人家初中,早就学完最大流最小割,还在最小费用流了,我却从来没有正式接触过
太丢脸了吧
所以今天尝试来写一下EK和DI

EK算法流程

1.初始化
2.bfs找到一条增广路
3.找到限制边残余量k,这条路上正向边都减去k,反向边残余流量都加上k。
4.重复步骤2直到不再有增广路存在

然后自己试着打了一下EK,woc竟然过了(想当年,我di写了好几万年......)

应该只有我会写这种vector的代码吧

重要代码实现:

1.vector怎么快速找反向边呢?

假设我现在已知u->v这条边我怎么快速找到v->u这条边呢?
很明显,我反向边建立的时候正是正向边建立的时候
所以,我可以记录一下对方vector存储的位置-->未存储前的size
为什么是未存前?这是因为vector是从0开始标号的,如果从1开始,我加入的这个位置肯定是size+1。

2.已知u,v,两者我都不知道具体存储位置怎么办?

这个也很简单,我利用了cb这个数组,cb(i,j)表示我第一次建立i->j这条边的时候,j存在vector(i)的哪个位置
那么很显然,这个值就是vector(i)的size
那么我利用mp(i,cb(i,j))就能找到i->j这条边具体位置

3.去重怎么办?

很明显的是同一条边具有可加性,然后判断下cb我是否已经赋值了,如果赋值了,就找到这条边然后加就行了

4.最后一定记住bfs及其小细节即可!

代码:

#include<bits/stdc++.h>
using namespace std;
#define int long long
struct node{
	int to;
	int c;//最大流量 
	int f;//残余流量,最开始就是c 
	int rev;//反向边在另一个地方的编号 ,即已知边u->v:在mp[v][rev]就正好是u处,正好就是反向边 
};
int n,m,s,t;
vector<node>mp[205];
vector<node>rev[205];
bool vis[205];
int dis[205];
int pre[205]; 
int cb[205][205];//重边可加性 ,值则是表示存储位置 
int ans=0;
bool bfs(){
	memset(vis,0,sizeof(vis));
	queue<int>q;
	vis[s]=1;
	dis[s]=2005020600;//从原点到达x点的最大流 
	q.push(s);
	while(q.size()){
		int tmp=q.front();
		q.pop();
		for(int i=0;i<mp[tmp].size();i++){
			if(mp[tmp][i].f==0){
				continue;
			}
			int to=mp[tmp][i].to;
			if(vis[to]){
				continue;
			}
			dis[to]=min(dis[tmp],mp[tmp][i].f);//这条路我只能流他剩下的 
			pre[to]=tmp;
			q.push(to);
			vis[to]=1;
			if(to==t){
				return 1;
			}
		}
	}
	return 0;
}
inline void updata() {  //更新所经过边的正向边权以及反向边权 
	int x=t;
	while(x!=s) {
		int to=pre[x];
		int id1=cb[x][to];
		mp[x][id1].f+=dis[t];
		int id=mp[x][id1].rev;
		mp[to][id].f-=dis[t];
		x=to;
	}
	ans+=dis[t];   //累加每一条增广路经的最小流量值 
}
void EK(){	
	while(bfs()!=0){
		updata();
	}
}
signed main(){
	ios::sync_with_stdio(false);
	cin >> n >> m >> s >> t;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			cb[i][j]=-1;
		}
	}
	for(int i=1;i<=m;i++){
		int u,v,w;
		cin >> u >> v >> w;
		if(cb[u][v]==-1){
			int revu=mp[u].size();
			int revv=mp[v].size();
			cb[u][v]=revu;
			cb[v][u]=revv;
			mp[u].push_back((node){v,w,w,revv});
			mp[v].push_back((node){u,w,0,revu});
		} 
		else{
			int id=cb[u][v];
			mp[u][id].c+=w;
			mp[u][id].f+=w;
			int id2=mp[u][id].rev;
			mp[v][id2].c+=w;
		}
		
	}
	EK();
	cout<<ans;
}

标签:205,int,cb,预习,vector,流试,mp,size
From: https://www.cnblogs.com/linghusama/p/17564343.html

相关文章

  • vector 容器的容量(capacity)和大小(size)之间的区别
    vector容器的容量(用capacity表示),指的是在不分配更多内存的情况下,也就是事先分配好内存大小,如果不超出容量即便有新的元素加入也不会分配内存空间;容器可以保存的最多元素个数;而vector容器的大小(用size表示),指的是它实际所包含的元素个数。对于一个vector对象来说,通过该......
  • C++ vector使用方法
    WARNING!本博文为算法笔记,恐说明错误,不建议参考本文膜拜大佬教程看不懂的教程......
  • Query2box Reasoning over Knowledge Graphs in Vector Space using Box Embeddings
    目录概符号说明Query2Box代码RenH.,HuW.andLeskovecJ.Query2box:Reasoningoverknowledgegraphsinvectorspaceusingboxembeddings.ICLR,2020.概Boxembedding用于查询判断,和我想的那个有很大差别啊.我对这方面不是很了解,只能记录个大概.符号说明......
  • C++ STL容器之vector、list
    (1)vector连续存储的容器,动态数组,在堆上分配空间底层实现:数组扩容机制:vector增加(插入)新元素时,如果未超过当时的容量,则还有剩余空间,那么直接添加到最后(插入指定位置),然后调整迭代器。如果没有剩余空间了,则会重新配置原有元素个数的两倍空间,然后将原空间元素通过复制的方式初始......
  • vector的相关操作
    插入元素:可以使用insert()函数在指定位置插入一个或多个元素。可以通过指定插入位置的迭代器和插入元素的值或范围来进行插入操作。例如:cppstd::vector<int>v={1,2,3,4,5};v.insert(v.begin()+2,10);//在第三个位置插入元素v.insert(v.begin()+3,3,7);......
  • 动态数组和C++ std::vector详解
    目录1.std::vector2.vector的用法    2.1vector的定义和声明    2.2成员函数        2.2.1基本函数            operator=            assign            get_allocator        2.2.2元素访问   ......
  • PostgreSQL向量数据库pgvector之ivfflat实践
    前言ChatGPT、OpenAI和大型语言模型(LLM)应用的不断普及,将近似近邻搜索(ANN)的概念推向了前沿,并由于嵌入的使用,引发了人们对向量数据库的重新关注。嵌入是短语的数学表示,它将语义捕捉为数值的向量量,鉴于嵌入通常由一千多个维度组成--OpenAI的维度为1,536,因此必须开发新的技术。目前还没......
  • Vectorworks 2023 mac|3D建筑设计软件
    Vectorworks2023mac(3D建筑设计软件)是一款全新的三维建筑设计软件,3D建筑设计软件拥有更多的功能,更加实用,更强大!Vectorworks2023mac的主要功能是设计和构建模型和渲染图,Vectorworks2023mac的主要功能还包括在线渲染、动画模拟和3D建模。在Vectorworks2023mac中,您可以进......
  • mystl——vector容器
    vector代码仓库:https://github.com/sjz-hub/mystl简介vector是向量,c++标准STL容器的一种特点顺序存储:容器元素严格按照线性顺序排序随机访问:支持[]和at(),时间复杂度是O(1)动态添加删除:支持在内部添加删除元素实现原理vector的成员变量iteratorbegin_指向存放的......
  • 算法竞赛中C++ vector的常规操作
    算法竞赛中C++vector的常规操作对vector的理解vector官方将其翻译为向量,但实际上是变长的动态数组,其可以存放各种类型的对象。vector定义语法大致格式:vector<类型>数组名在初始情况下,vector的大小是0,也就是空的数组。下面都以int型举例。vector<int>v;/......