网络流模板

陈年模板,不如看这里

最大流

【模板】网络最大流(洛谷)

dinic

int head[MAXN],tot = 1;
struct edge
{
	int v,nxt;LL w;
}e[MAXM << 1];
void Add_Edge(int x,int y,LL z)
{
	e[++tot].v = y;
	e[tot].w = z;
	e[tot].nxt = head[x];
	head[x] = tot;
}
int d[MAXN];
bool bfs(int s,int t)
{
	for(int i = 1;i <= n;++ i) d[i] = -1;
	d[s] = 0;
	queue<int> q; q.push(s);
	while(!q.empty())
	{
		int p = q.front(); q.pop();
		for(int i = head[p]; i ;i = e[i].nxt)
			if(d[e[i].v] == -1 && e[i].w > 0)
			{
				d[e[i].v] = d[p] + 1;
				q.push(e[i].v);
			}
	}
	return d[t] != -1;
}
int cur[MAXN];
LL dfs(int x,LL flow,int t)
{
	if(x == t) return flow;
	LL ret = 0;
	for(int &i = cur[x]; i ;i = e[i].nxt)
	{
		if(d[x] + 1 == d[e[i].v] && e[i].w > 0)
		{
			LL dz = dfs(e[i].v,Min(flow-ret,e[i].w),t);//记得是flow-ret而不是flow!!!(货物变多可还行 
			e[i].w -= dz; e[i^1].w += dz;
			if((ret += dz) == flow) break;
		}
	}
	if(!ret) d[x] = -1;
	return ret;
}
LL dinic(int s,int t)
{
	LL ret = 0;
	while(bfs(s,t))
	{
		for(int i = 1;i <= n;++ i) cur[i] = head[i];
		ret += dfs(s,INF,t);
	}
	return ret;
}

int main()
{
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);
	n = Read(); m = Read(); s = Read(); t = Read();
	for(int i = 1,u,v,w;i <= m;++ i)
	{
		u = Read(),v = Read(),w = Read();
		Add_Edge(u,v,w);
		Add_Edge(v,u,0);
	}
	Put(dinic(s,t));
	return 0;
}

最小费用最大流

【模板】最小费用最大流(洛谷)

单路
int head[MAXN],tot = 1;//tot初值一定要是1啊啊啊啊啊啊啊啊啊 
struct edge
{
	int v,w,c,nxt;
}e[MAXM << 1];
void Add_Edge(int u,int v,int w,int c)
{
	e[++tot].v = v;
	e[tot].w = w;
	e[tot].c = c;
	e[tot].nxt = head[u];
	head[u] = tot;
}

int pre[2][MAXN],dis[MAXN],flow[MAXN],maxflow,maxcost;
bool vis[MAXN];
bool bfs(int s,int t)
{
	for(int i = 1;i <= n;++ i) dis[i] = INF;
	queue<int> q; q.push(s);
	flow[s] = INF; dis[s] = 0; 
	while(!q.empty())
	{
		int p = q.front(); q.pop();
		vis[p]= 0;
		for(int i = head[p]; i ;i = e[i].nxt)
		{
			if(dis[p] + e[i].c < dis[e[i].v] && e[i].w > 0)
			{
				dis[e[i].v] = dis[p] + e[i].c;
				pre[0][e[i].v] = p;
				pre[1][e[i].v] = i;
				flow[e[i].v] = Min(flow[p],e[i].w);
				if(!vis[e[i].v])
				{
					vis[e[i].v] = 1;
					q.push(e[i].v);
				}
			}
		}
	}
	return dis[t] != INF;
}
void MCMF(int s,int t)
{
	while(bfs(s,t))
	{
		maxflow += flow[t];
		maxcost += flow[t] * dis[t];
		for(int now = t;now != s;now = pre[0][now])
		{
			e[pre[1][now]].w -= flow[t];
			e[pre[1][now]^1].w += flow[t];
		}
	}
}

int main()
{
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);
	n = Read(); m = Read(); s = Read(); t = Read();
	for(int i = 1,u,v,w,c;i <= m;++ i)
	{
		u = Read(); v = Read(); w = Read(); c = Read();
		Add_Edge(u,v,w,c);
		Add_Edge(v,u,0,-c);
	}
	MCMF(s,t);
	Put(maxflow,' '),Put(maxcost);
	return 0;
}
多路(听说叫zkw)
//12252024832524
#include <bits/stdc++.h>
#define TT template<typename T>
using namespace std; 

typedef long long LL;
const int MAXN = 5005;
const int MAXM = 50005;
const int INF = 2147483647;
int n,m,S,T;

LL Read()
{
	LL x = 0,f = 1;char c = getchar();
	while(c > '9' || c < '0'){if(c == '-')f = -1;c = getchar();}
	while(c >= '0' && c <= '9'){x = (x*10) + (c^48);c = getchar();}
	return x * f;
}
TT void Put1(T x)
{
	if(x > 9) Put1(x/10);
	putchar(x%10^48);
}
TT void Put(T x,char c = -1)
{
	if(x < 0) putchar('-'),x = -x;
	Put1(x); if(c >= 0) putchar(c);
}
TT T Max(T x,T y){return x > y ? x : y;}
TT T Min(T x,T y){return x < y ? x : y;}
TT T Abs(T x){return x < 0 ? -x : x;}

int head[MAXN],tot = 1;
struct edge{
	int v,w,c,nxt;
}e[MAXM<<1];
void Add_Edge(int u,int v,int w,int c){
	e[++tot] = edge{v,w,c,head[u]};
	head[u] = tot;
}
void Add_Double_Edge(int u,int v,int w,int c){
	Add_Edge(u,v,w,c);
	Add_Edge(v,u,0,-c);
}

int dis[MAXN],cur[MAXN],maxflow,mincost;
bool inq[MAXN],vis[MAXN];
bool bfs(int S,int T){
	for(int i = 1;i <= n;++ i) dis[i] = INF;
	queue<int> q; q.push(S); dis[S] = 0;
	while(!q.empty()){
		int x = q.front(); q.pop(); inq[x] = 0;
		for(int i = head[x],v; i ;i = e[i].nxt)
			if(e[i].w && dis[x] + e[i].c < dis[v = e[i].v]){
				dis[v] = dis[x] + e[i].c;
				if(!inq[v])	inq[v] = 1,q.push(v);
			}
	}
	return dis[T] < INF;
}
int dfs(int x,int flow,int T) {
	if(x == T) return flow;
	int ret = 0; vis[x] = 1;
	for(int &i = cur[x],v; i ;i = e[i].nxt)
		if(e[i].w && dis[x] + e[i].c == dis[v = e[i].v] && !vis[v]){
			int dz = dfs(v,Min(flow-ret,e[i].w),T);
			e[i].w -= dz; e[i^1].w += dz;
			if((ret += dz) == flow) break;
		}
	vis[x] = 0;
	return ret;
}
void MCMF(int S,int T){
	while(bfs(S,T)){
		for(int i = 1;i <= n;++ i) cur[i] = head[i];
		int ret = dfs(S,INF,T);
		maxflow += ret,mincost += ret * dis[T];
	} 
}

int main()
{
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);
	n = Read(); m = Read(); S = Read(); T = Read();
	for(int i = 1,u,v,w;i <= m;++ i){
		u = Read(),v = Read(),w = Read();
		Add_Double_Edge(u,v,w,Read());
	}
	MCMF(S,T);
	Put(maxflow,' '),Put(mincost,'\n');
	return 0;
}
posted @ 2021-02-05 10:37  皮皮刘  阅读(47)  评论(0编辑  收藏  举报