网络最大流:dinic算法

改日再详写算法

例题:点击这里

#include <cstdio>
#include <cstring>//建议使用ISAP算法
#include <vector>
#include<queue>
#include<iostream>
#include <algorithm>
#define maxd 10000+5
#define maxm 100000+5
const int inf=0x7ffffff;
using namespace std;
int n,m,s,t;
struct Edge{
    int to;
    int w;
    int next;
} edge[210000];
int head[maxd];
int cur[maxd];
int dep[maxd];
int edge_num=-1;
void addEdge2(int from, int to, int dis){
    edge[++edge_num].to = to;
    edge[edge_num].w = dis;
    edge[edge_num].next = head[from];
    head[from] = edge_num;
}
void addEdge(int from, int to, int dis){
    addEdge2(from, to, dis), addEdge2(to, from, 0);
}
int dfs(int u,int flow){//dfs求増广路 ,u是当前节点,flow是当前流量 
	if(u==t) return flow;//到达汇点,返回 
	int flowsum=0,flowmin;
	for(int& i=cur[u];i!=-1;i=edge[i].next){//遍历与u 相连的所有节点 
		int v=edge[i].to;
		if(dep[v]==dep[u]+1&&edge[i].w>0){//满足层次且流量大于0 
			flowmin=dfs(v,min(flow,edge[i].w));//flowmin表示该増广路中拥有最小流量的边的流量
			flow-=flowmin;//当前流量 
			edge[i].w-=flowmin;//每条边的权都减去该增广路中拥有最小流量的边的流量
			flowsum+=flowmin;//要求的总流量 
			edge[i^1].w+=flowmin;//将每条边的反向边的权增加这个值
			if(!flow) break;
		}
	}
	if (!flowsum) dep[u] = -1;
    return flowsum;
}
bool bfs(){//dinic算法用bfs分层 
	memset(dep,-1,sizeof(dep));
	queue<int>q;
	q.push(s);
	dep[s]=0;
	int u,v;
	while(!q.empty()){
		u=q.front();
		q.pop();
		for(int i=head[u];i!=-1;i=edge[i].next){
			v=edge[i].to;
			if(dep[v]==-1&&edge[i].w>0){
				dep[v]=dep[u]+1;
				q.push(v);
			}
		}
	}
	return (dep[t]!=-1);
}
int dinic(){
    int max_flow = 0;
    while (bfs()){
        for (int i = 1; i <= n; ++i) cur[i] = head[i];
        max_flow += dfs(s, inf);
    }
    return max_flow;
}
int main() {
	scanf("%d%d%d%d",&n,&m,&s,&t);
	memset(head,-1,sizeof(head));
	for(int i=0;i<m;i++){
		int u,v,w;
		scanf("%d%d%d",&u,&v,&w);
		addEdge(u,v,w);
	}
	printf("%d",dinic());
	return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值