#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=3e5;
const int INF=0x3f3f3f3f;
struct Edge{
int u,v,cap,flow;
};
int n,m,s,t;
vector<Edge>edges;
vector<int>G[maxn];
int vis[maxn];
int d[maxn];
int cur[maxn];
void init(){
edges.clear();
for(int i=0;i<maxn;i++)G[i].clear();
}
int BFS(){
memset(vis,0,sizeof vis);
queue<int>Q;
Q.push(s);
d[s]=0;
vis[s]=1;
while(!Q.empty()){
int x=Q.front();Q.pop();
for(int i=0;i<G[x].size();i++){
Edge &e=edges[G[x][i]];
if(!vis[e.v] && e.cap>e.flow){
vis[e.v]=1;
d[e.v]=d[x]+1;
Q.push(e.v);
}
}
}
return vis[t];
}
void addedge(int u,int v,int cap){
edges.push_back((Edge){u,v,cap,0});
edges.push_back((Edge){v,u,0,0});
m=edges.size();
G[u].push_back(m-2);
G[v].push_back(m-1);
}
int DFS(int x,int a){
if(x==t||a==0)return a;
int flow=0,f;
for(int& i=cur[x];i<G[x].size();i++){
Edge& e=edges[G[x][i]];
if(d[x]+1==d[e.v] && (f=DFS(e.v,min(a,e.cap-e.flow)))>0){
e.flow+=f;
edges[G[x][i]^1].flow-=f;
flow+=f;
a-=f;
if(a==0)break;
}
}
return flow;
};
int maxflow(int _s,int _t){
s=_s;t=_t;
int flow=0;
while(BFS()){
memset(cur,0,sizeof cur);
flow+=DFS(_s,INF);
}
return flow;
}
BFS对残量网络进行层次图距离测算,DFS贪婪扩充
DFS(x,a)表示当前位于x节点,有a的最大流到达x
当a为0的时候意味着已经访问过的x的后继点已经可以把a全部输送到终点,那么x的其他后继点就不用再从x访问了
当前弧优化就记录了x点之前被访问过的后继点
//#include<bits/stdc++.h>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<string>
#include<vector>
#include<queue>
#include<iostream>
//#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
#define ll long long
const int maxn=2e5;
const int INF=0x3f3f3f3f;
int d[maxn], cur[maxn], start, tend;
struct node
{
int to, cap, next;
}edge[maxn << 1];
int head[maxn];
bool vis[maxn];
int cnt;
void init(){
memset(head,-1,sizeof head);
cnt=0;
}
void addedge(int start, int to, int cap)
{
edge[cnt].to = to;
edge[cnt].cap = cap;
edge[cnt].next = head[start];
head[start] = cnt++;
}
bool BFS()
{
memset(d, -1, sizeof(d));
int Q[maxn * 2];
int Thead, Ttail;
Thead = Ttail = 0;
Q[Ttail++] = start;;
d[start] = 0;
while (Thead<Ttail)
{
int x = Q[Thead];
if (x == tend)return true;
for (int i = head[x]; i != -1; i = edge[i].next)
{
int temp = edge[i].to;
if (d[temp] == -1 && edge[i].cap>0)//没有标记,且可行流大于0
{
d[temp] = d[x] + 1;
Q[Ttail++] = temp;
}
}
Thead++;
}
return false;//汇点是否成功标号,也就是说是否找到增广路
}
int DFS(int x, int cap)
{
if (x == tend)return cap;
int flow = 0, f;
for (int i = head[x]; i != -1; i = edge[i].next)
{
int temp = edge[i].to;
if (d[temp] == d[x] + 1 && edge[i].cap)
{
f = DFS(temp, min(cap - flow, edge[i].cap));
edge[i].cap -= f;
edge[i ^ 1].cap += f;
flow += f;
if (flow == cap)break;
}
}
if (!flow)d[x] = -2;//防止重搜
return flow;
}
int maxflow()
{
int flow = 0, f;
while (BFS())
{
while ((f = DFS(start, INF))>0)
flow += f;
}
return flow;
}
原模板似乎有些低效,补一个高效一些的
链式前向星+数组模拟队列
以后应该会用isap吧。。?