网络最大流算法小结
2014-04-30 21:13
351 查看
1. EK
2.Push-Relabel
3、Relabel-to-Front
4.Sap
5、Dinic
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; }
相关文章推荐
- 网络最大流问题算法小结 [转]
- USACO 4.2.1 Ditch 网络最大流问题算法小结
- 转】USACO 4.2.1 Ditch 网络最大流问题算法小结
- 网络最大流问题算法小结
- 网络最大流问题算法小结
- USACO 4.2.1 Ditch 网络最大流问题算法小结
- 网络最大流问题算法小结 [转]
- HDU 3549 Flow Problem 网络最大流问题 EK、Dinic、ISAP三种算法
- 网络最大流算法—最高标号预流推进HLPP
- 增广路算法 Ford-Fulkerson算法 网络最大流问题
- 最小割集Stoer-Wagner算法,网络最大流问题
- 最大流算法小结
- 网络最大流算法之 Ford_Fulkerson方法,EK算法 c++模板
- 网络最大流问题算法 —— Dinic 算法 && poj 1237
- 网络最大流问题之Ford-Fulkerson算法原理详解
- 图论专题小结:最大流算法之Dinic算法
- 图论专题小结:最大流算法之ISAP算法
- 神经网络梯度下降优化算法及初始化方法小结
- 最大流算法小结
- 一种精确的基于DHT的p2p网络搜索算法与网络拓扑模型