网络最大流算法小结

1. EK

编码请看:http://www.maidoupig.cn

const int MN = 400;
int que[MN];
bool visited[MN];
int head,tail;
int map[MN][MN];
int pre[MN];
int N,M;
bool bfs(){
	int i,j,k;
	memset(visited,0,sizeof(visited));
	head = tail = 0;
	que[tail++] =  1;
	visited[1] = true;
	while(head != tail){
		k = que[head++];
		for(i = 1; i <= M; i++){
			if(!visited[i] && map[k][i]){
				pre[i] = k;
				if(i == M) return true;
				que[tail++] = i;
				visited[i] =  true;
			}
		}
	}
	return false;
}

int solve(){
	int i,j,k, ans = 0;
	while(bfs()){
		i = M, j = INT_MAX;
		while(i != 1){
			k = map[pre[i]][i];
			if(j > k) j = k;
			i = pre[i];
		}
		i = M;
		ans += j;
		while(i != 1){
			map[pre[i]][i] -= j;
			map[i][pre[i]] += j;
			i = pre[i];
		}
	}
	return ans;
}


2.Push-Relabel

 

 

const int MN = 1024;
int h[MN],e[MN], s,t,n,G[MN][MN];//n为顶点个数,G[i][j]代表残留网络c(i,j)
int que[MN],head,tail;
bool inque[MN];
void inline push(int u, int v){
	int d = min(e[u],G[u][v]);
	G[u][v] -= d;
	G[v][u] += d;
	e[u] -= d;
	e[v] += d;
	if(v != t && v != s && !inque[v]){
		que[tail] = v;
		tail = (tail + 1) % MN; 
		inque[v] = true;
	}
}
void inline relabel(int u, int m){
	if(m < INT_MAX) h[u] = m + 1;
	que[tail] = u; tail = (tail + 1) % MN;
	inque[u] = true;
}

void init(){
	memset(h,0,sizeof(h));
	memset(e,0,sizeof(e));
	memset(inque,0,sizeof(inque));
	h[s] = n;
	e[s] = INT_MAX;
	head = tail = 0;
}

int push_relabel(){
	init();
	inque[s] = true;
	que[tail++] = s;
	while(head != tail){
		int u = que[head]; head = (head + 1) % MN;
		inque[u] = false;  int mm = INT_MAX;
		for(int v = 1; v <= n && e[u] > 0; v++){
			if(G[u][v]){
				if(u == s || h[u] == h[v] + 1){
					push(u,v);
				}
				if(mm > h[v]) mm = h[v];
			}
		}
		if(e[u] > 0 && u != s && u != t) relabel(u,mm);//所有能压入到相邻顶点到压入了,所以如是u还有余流就一定要重标记才可以再有容许边
	}
	return e[t];
}


3、Relabel-to-Front

 

 

const int MN = 1024;
int h[MN],e[MN], s,t,n,G[MN][MN];//n为顶点个数,G[i][j]代表残留网络c(i,j)

struct Node{
	int v;
	bool operator <(const Node a)const{
		return h[v] < h[a.v];
	}
	Node(int u):v(u){}
};
bool inque[MN];
priority_queue<Node> pque;

void inline push(int u, int v){
	int d = min(e[u],G[u][v]);
	G[u][v] -= d;
	G[v][u] += d;
	e[u] -= d;
	e[v] += d;
	if(v != t && v != s && !inque[v]){
		pque.push(Node(v));
		inque[v] = true;
	}
}
void inline relabel(int u, int m){
	if(m < INT_MAX) h[u] = m + 1;
}

void init(){
	memset(h,0,sizeof(h));
	memset(e,0,sizeof(e));
	h[s] = n;
	e[s] = INT_MAX;
	for(int v = 1; v <= n; v++){
		if(G[s][v]){
			push(s,v);
		}
	}
}

void discharge(int u){
	while(e[u] > 0){
		int mm = INT_MAX;
		for(int v = 1; v <= n && e[u] > 0; v++){
			if(G[u][v]){
				if(h[u] == h[v] + 1){
					push(u,v);
				}
				if(mm > h[v]) mm = h[v];
			}
		}
		if(e[u] > 0) relabel(u,mm);
	}
}

int push_relabel(){
	init();
	while(!pque.empty()){
		int u = pque.top().v; pque.pop(); inque[u] = false;
		discharge(u);
	}
	return e[t];
}


4.Sap

 

 

int N,pe,S = 0,T;
double D;
const int MN = 204;
const int INF = 1 << 30;
int cap[MN][MN];
int map[MN][MN];
int X[MN],Y[MN];
double inline getD(int x, int y ,int x1,int y1){
	double dx = x1 - x, dy = y1 - y;
	return sqrt(dx * dx + dy * dy);
}

void addedge(){
	double dist;
	for(int i = 1; i < N; i++){
		for(int j = i + 1; j <= N; j++){
			dist = getD(X[i],Y[i],X[j],Y[j]);
			if(dist <= D){
				cap[j + N][i] = INF;
				cap[i + N][j] = INF;
			}
		}
	}
}
int que[1000000],qh,qt;
int h[MN],num[MN];
int pre[MN];
void init(){
	qh = qt = 0;
	memset(h,-1,sizeof(h));
	memset(num,0,sizeof(num));
	h[T] = 0;
	que[qt++] = T;
	while(qh != qt){
		int u = que[qh++];
		for(int v = S; v <= 2 * N; v++){
			if(h[v] == -1 && map[v][u] > 0){
				h[v] = h[u] + 1;
				que[qt++] = v;
				num[h[v]]++;
			}
		}
	}
}

int find(int u){
	for(int v = S; v <= 2 * N; v++){
		if(map[u][v] > 0 && h[u] == h[v] + 1){
			return v;
		}
	}
	return -1;
}

int relable(int u){
	int minn = INF;
	for(int v = S; v <= 2 * N; v++){
		if(map[u][v] > 0 && minn > h[v]){
			 minn = h[v];
		}
	}
	if(minn != INF) return minn + 1;
	return 2 * N + 1;
}
int flow(){
	init();
	memset(pre,-1,sizeof(pre));
	int i = S,j,flow = 0;
	while(h[S] <= 2 * N){
		j = find(i);
		if(j >= 0){
			pre[j] = i;
			i = j;
			if(i == T){
				int minn = INF;
				i = T;
				while(i != S){
					if(minn > map[pre[i]][i]) minn = map[pre[i]][i];
					i = pre[i];
				}
				i = T;
				while(i != S){
					map[pre[i]][i] -= minn;
					map[i][pre[i]] += minn;
					i = pre[i];
				}
				flow += minn;
			}
		}else{
			int m = relable(i);
			num[m]++;
			num[h[i]]--;
			if(num[h[i]] == 0) return flow;
			h[i] = m;
			if(i != S){
				i = pre[i];
			}
		}
	}
	return flow;
}


5、Dinic

 

 

const int MAXN=510;
const int MAXE=510;
const int INF = (1<<30)-1;
struct Edge{
	int v,c,next;
}edge[MAXE];
int head[MAXN],pn;
void initEdge(){
	memset(head,-1,sizeof(head));
	pn = 0;
}
void addEdge(int u,int v,int c){
	edge[pn].v = v;
	edge[pn].c = c;
	edge[pn].next = head[u];
	head[u] = pn++;
}
int S,T;
queue<int> que;
int d[MAXN]; //dinic层次图层次
bool bfs(){
	memset(d,0,sizeof(d));
	d[S]=1;
	que.push(S);
	while(!que.empty()){
		int u = que.front(); que.pop();
		for(int e = head[u]; e!=-1;e=edge[e].next){
			int v=edge[e].v;
			if(!d[v]&&edge[e].c>0){
				d[v]=d[u]+1;
				que.push(v);
			}
		}
	}
	return d[T];
}
int dfs(int x,int a){
	if(x==T||a==0) return a;
	int flow=0,f;
 	for(int e=head[x]; e!=-1; e=edge[e].next){
		int v=edge[e].v;
		if(d[v]==d[x]+1&&(f=dfs(v,min(a,edge[e].c)))>0){
			edge[e].c-=f;
			edge[e^1].c+=f;
			flow+=f;
			a-=f;
			if(a==0) break;
		}
	}
	return flow;
}
int dinic(){
	int flow=0;
	while(bfs()){
		flow += dfs(S,INF); 
	}
	return flow;
}

 

 

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值