最大流Dinic算法:
1、先利用BFS对残余网络分层(一个节点的层数就是它到源点最少要经过的边数)
2、分层完了以后,从源点开始,利用DFS从前一层向后一层反复寻找增广路。
算法时间的复杂度为n*n*m(n是点数,m是边数)
poj1273 最大流算法模板题目(Dinic算法实现)
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<cctype>
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
#include<map>
#include<string>
#include<stack>
#include<set>
#define ll long long
#define MAX 1000
#define INF INT_MAX
#define eps 1e-8
using namespace std;
struct Edge{
int from,to,cap,flow;
};
vector<int>G[MAX];
vector<Edge>edges;
int n;
void init(){
for (int i=0; i<=n; i++) G[i].clear();
edges.clear();
}
void addEdge(int from, int to, int cap){
edges.push_back((Edge){from,to,cap,0});
edges.push_back((Edge){to,from,0,0}); //添加反向边
int k = edges.size();
G[from].push_back(k-2);
G[to].push_back(k-1);
}
int d[MAX];
bool bfs(int s, int t){
bool vis[MAX];
queue<int>q;
memset(vis,false,sizeof(vis));
d[s] = 0;
q.push(s);
vis[s] = true;
while (!q.empty()){
int u = q.front();
q.pop();
for (int i=0; i<G[u].size(); i++){
Edge e = edges[G[u][i]];
if (!vis[e.to] && e.cap > e.flow){
vis[e.to] = true;
d[e.to] = d[u] + 1;
q.push(e.to);
}
}
}
return vis[t];
}
int cur[MAX];
int dfs(int s, int t, int a){
if (s == t || a == 0) return a;
int flow = 0, f;
for (int&i = cur[s]; i < G[s].size(); i++){
Edge& e = edges[G[s][i]];
if (d[s] + 1 == d[e.to] && (f = dfs(e.to,t,min(a,e.cap - e.flow))) > 0){
e.flow += f;
edges[G[s][i]^1].flow -= f;
flow += f;
a -= f;
if (a == 0) break;
}
}
return flow;
}
int Maxflow(int s, int t){ //s为源点,t为汇点的最大流
int flow = 0;
while (bfs(s,t)){
memset(cur,0,sizeof(cur));
flow += dfs(s,t,INF);
}
return flow;
}
int main(){
int m;
while (scanf("%d%d",&m,&n) != EOF){
init();
int x,y,z;
for (int i=0; i<m; i++){
scanf("%d%d%d",&x,&y,&z);
addEdge(x,y,z);
}
printf("%d\n",Maxflow(1,n));
}
return 0;
}
ISAP算法+gap优化
poj1273最大流问题(ISAP实现)
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<cctype>
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
#include<map>
#include<set>
#include<string>
#include<stack>
#define ll long long
#define MAX 1000
#define eps 1e-8
#define INF INT_MAX
using namespace std;
struct Edge{
int from, to,cap,flow;
};
vector<int>G[MAX],T[MAX]; //T用来记录G的转置,用于下面逆向bfs遍历图
vector<Edge>edges;
int n;
void init(){
for (int i=0; i<=n; i++){
G[i].clear();
T[i].clear();
}
edges.clear();
}
void addEdge(int from, int to, int cap){
edges.push_back((Edge){from,to,cap,0});
edges.push_back((Edge){to,from,0,0});
int k = edges.size();
G[from].push_back(k-2);
G[to].push_back(k-1);
}
int d[MAX];
void bfs(int s, int t){
bool vis[MAX];
queue<int>q;
memset(vis,false,sizeof(vis));
q.push(s);
d[s] = 0;
vis[s] = true;
while (!q.empty()){
int u = q.front();
q.pop();
for (int i=0; i<T[u].size(); i++){
int v = T[u][i];
if (!vis[v]){
d[v] = d[u] + 1;
vis[v] = true;
q.push(v);
}
}
}
}
int p[MAX],num[MAX],cur[MAX];
int Augment(int s, int t){
int x = t, a = INF;
while (x != s){
Edge& e = edges[p[x]];
a = min(a,e.cap - e.flow);
x = edges[p[x]].from;
}
x = t;
while (x != s){
edges[p[x]].flow += a;
edges[p[x]^1].flow -= a;
x = edges[p[x]].from;
}
return a;
}
int Maxflow(int s, int t){
int flow = 0;
bfs(t,s); //逆向bfs
memset(num,0,sizeof(num));
for (int i=1; i<=n; i++) num[d[i]]++; //注意此处i应该为节点的编号的变化范围
int x = s;
memset(cur,0,sizeof(cur));
while (d[s] < n){ //此处n应该为节点的数量
if (x == t){
flow += Augment(s,t);
x = s;
}
int ok = 0;
for (int i=cur[x]; i<G[x].size(); i++){
Edge& e = edges[G[x][i]];
if (e.cap > e.flow && d[x] == d[e.to] + 1){
ok = 1;
p[e.to] = G[x][i];
cur[x] = i;
x = e.to;
break;
}
}
if (!ok){
int m = n-1;
for (int i=0; i<G[x].size(); i++){
Edge& e = edges[G[x][i]];
if (e.cap > e.flow) m = min(m,d[e.to]);
}
if (--num[d[x]] == 0) break; //gap优化,能使时间复杂度降低100倍左右
num[d[x] = m+1]++;
cur[x] = 0;
if (x != s) x = edges[p[x]].from;
}
}
return flow;
}
int main(){
int m;
while (scanf("%d%d",&m,&n) != EOF){
int x,y,z;
init();
for (int i=0; i<m; i++){
scanf("%d%d%d",&x,&y,&z);
addEdge(x,y,z);
T[y].push_back(x);
}
printf("%d\n",Maxflow(1,n));
}
return 0;
}