最大流 EK() 复习用

链式前向星存储数据

struct node {
	int to, con, ne;//终点,容量,下一条边地编号
}edge[M];

int h[N];

int idx = 1;

void add(int a,int b,int c)
{
	edge[++idx] = { b,c,h[a]};
	h[a] = idx;
}

宽搜搜索增广路

bool bfs()
{
	memset(mf, 0, sizeof(mf));//mf[]存放最大流值,匹配前初始化为0
	mf[s] = 1e9;//起点初始化为最大值
	queue<int> q;
	q.push(s);
	while (q.size())
	{
		int u = q.front(); q.pop();
		for (int i = h[u];i; i = edge[i].ne)//临边
		{
			ll v = edge[i].to;
			if (mf[v] == 0 && edge[i].con)//为匹配且容量不为0
			{
				mf[v] = min(mf[u], edge[i].con);//终点地mf[]值为上一点地mf[]值和容量取最小值
				q.push(v);
				pre[v] = i;//记录点v地上一条边编号
				if (v == t)
					return 1;//到达汇点
			}
		}
	}
	return 0;
}

EK()

ll EK()
{
	ll flow = 0;//最大流
	while (bfs())//每次地增广路
	{
		int v = t;
		while (v != s)//反向更新
		{
			int i = pre[v];//pre[]存放当前点地上一条边编号
			edge[i].con -= mf[t];//对此边和反向边更新
			edge[i ^ 1].con += mf[t];//与1异或即末位取反
			v = edge[i ^ 1].to;
		}
		flow += mf[t];
	}
	return flow;
}
#include<iostream>
#include<vector>
#include<cstring>
#include<string>
#include<queue>
using namespace std;
const int M = 80000;
const int N =80000;
typedef long long ll;
ll n,m;
int s, t;
int idx = 1;
struct node {
	int to, con, ne;
}edge[M];
int h[N];
int mf[N], pre[N];
void add(int a,int b,int c)
{
	edge[++idx] = { b,c,h[a]};
	h[a] = idx;
}
bool bfs()
{
	memset(mf, 0, sizeof(mf));
	mf[s] = 1e9;
	queue<int> q;
	q.push(s);
	while (q.size())
	{
		int u = q.front(); q.pop();
		for (int i = h[u];i; i = edge[i].ne)
		{
			ll v = edge[i].to;
			if (mf[v] == 0 && edge[i].con)
			{
				mf[v] = min(mf[u], edge[i].con);
				q.push(v);
				pre[v] = i;
				if (v == t)
					return 1;
			}
		}
	}
	return 0;
}

ll EK()
{
	ll flow = 0;
	while (bfs())
	{
		int v = t;
		while (v != s)
		{
			int i = pre[v];
			edge[i].con -= mf[t];
			edge[i ^ 1].con += mf[t];
			v = edge[i ^ 1].to;
		}
		flow += mf[t];
	}
	return flow;
}

  • 10
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值