1. EK
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;
}