最大流定义过掉,算法叫Ford-Fulkerson算法 对于原始图,每条边e,容量为c(e),当前流量为f(e), 加一条反向边re,容量为0,
算法步骤:
1. 在残余网络中不断寻找可以从起点到终点的路径,这条路径允许的流量为d
2. 路径中每条边e, c(e) -= d; c(re)+=d;
3. 反复1.2直到找不到了
最大流代码
#include <vector>
#include <algorithm>
using namespace std;
const int MAXV = 100; //最大点数量
const int INF = 1000000;
//终点,容量,反向边
struct edge {int to,cap,rev;};
vector<edge> G[MAXV];
bool used[MAXV];
void add_edge(int from, int to ,int cap){
edge e1 = {from,cap,G[to].size()};
G[from].push_back(e1);
edge e2 = {to,0,G[from].size()-1};
G[to].push_back(e2);
}
int dfs(int v,int t,int f){
if(v==t){
return f;
}
used[v] = true;
for(int i=0;i<G[v].size();i++){
edge &e = G[v][i];
if(!used[e.to]&&e.cap>0){
int d = dfs(v,e.to,min(f,e.cap));
if(d>0){
e.cap -= d;
G[e.to][e.rev].cap += d;
return d;
}
}
}
return 0;
}
int max_flow(int s,int t){
int flow = 0;
while(true){
memset(used,0,sizeof(used));
int f = dfs(s,t,INF);
if(f==0){
return flow;
}
flow += f;
}
}
二分匹配
最大流的特殊情况,两个定点集合U,V,U,V之间不相连,U,V之间有线相连,选若干边M,M中无公共节点,M为一个匹配
代码
#include <stdio.h>
#include <vector>
using namespace std;
const int MAXV = 210;
int V; //定点数
vector<int> G[MAXV];
int match[MAXV]; //匹配的定点
bool used[MAXV];
void add_edge(int u,int v)
{
G[u].push_back(v);
G[v].push_back(u);
}
bool dfs(int v){
used[v] = true;
for(int i=0;i<G[v].size();i++){
int u = G[v][i],w = match[u];
if(w<0||!used[w]&&dfs(w)){
match[v] = u;
match[u] = v;
return true;
}
}
return false;
}
int bipartitie_matching()
{
int res = 0;
memset(match,-1,sizeof(match));
for(int v=0;v<V;v++){
if(match[v]<0){
memset(used,0,sizeof(used));
if(dfs(v)){
res++;
}
}
}
return res;
}