最大流模板

#include<bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof(a))
#define For(a,b,c) for(int a = b;a <= c;a++)
using namespace std;
typedef long long ll;
const int maxn = 1000005;
const int INF = 0x3f3f3f3f;
const int e_maxn = 1000 * 4;
const int v_maxn = 500;
struct ppp
{
	int v,nex,cap,flow,c;//分别为下一个点,下一条边,当前边容量和流量,还有费用
}e[e_maxn];
int head[v_maxn],dis[v_maxn],cur[v_maxn];//链表头节点,层次图中每个点所属层次,dfs所用的临时链表头
int tole,N,M,s,t;//总加入边数,总输入点数和总输入边数,源点和汇点
void make_edge(int u,int v,int cap,int c)//求最大流时费用不必考虑,可以省去,加上也没关系
{
	e[tole].v = v;e[tole].flow = 0;e[tole].cap = cap;e[tole].c = c;e[tole].nex = head[u];head[u] = tole++;
}
void add_edge(int u,int v,int cap,int c)
{
	make_edge(u,v,cap,c);//正向边容量为cap,费用为c
	make_edge(v,u,0,-c);//反向边容量为0,费用为-c
}
int bfs()//其中s为源点,t为汇点
{
	queue<int> que;
	que.push(s);
	mem(dis,-1);
	dis[s] = 0;
	int temp,v;
	while(!que.empty())
	{
		temp = que.front();
		que.pop();
		for(int i = head[temp];~i;i = e[i].nex)
		{
			v = e[i].v;
			if(dis[v] == -1 && e[i].cap > e[i].flow)
			{
				dis[v] = dis[temp] + 1;
				que.push(v);
			}
		}
	}
	return dis[t] != -1;
}

int dfs(int x,int a)
{
	if(x == t || !a) return a;
	int v,f,ret = 0;
	for(int &i = cur[x];~i;i = e[i].nex)
	{
		v = e[i].v;
		if((dis[v] == dis[x] + 1) && (f = dfs(v,min(a,e[i].cap - e[i].flow))) > 0)
		{
			e[i].flow += f;
			e[i ^ 1].flow -= f;
			a -= f;
			ret += f;
			if(!a)break;
		}
	}
	return ret;
}

void Dinic(int &ans)//ans为最大流
{
	while(bfs())
	{
		for(int i = 0;i <= t;i++)cur[i] = head[i];
		ans += dfs(s,INF);
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值