最大流
const int N=5e2+10,M=26,INF=1e9;
namespace Flow{
const int V=N+M,E=N*M*2+N*2+M*2+V*2;
int s,t,kk,head[V],d[V],cur[V];
struct edges{
int to,c,nex;
}edge[E];
void init(int x,int y){
s=x,t=y,kk=1;
fill(head+s,head+1+t,0);
}
bool chk(int i){
return !edge[i].c;
}
int add(int u,int v,int c){
// debug(u,v,c);
edge[++kk]={v,c,head[u]},head[u]=kk;
edge[++kk]={u,0,head[v]},head[v]=kk;
return kk-1;
}
bool bfs(){
queue<int>q;
q.push(s);
copy(head+s,head+1+t,cur+s);
fill(d+s,d+1+t,-1),d[s]=0;
for(int u;!q.empty();){
u=q.front(),q.pop();
for(int i=head[u];i;i=edge[i].nex){
int v=edge[i].to;
if(edge[i].c&&!~d[v])d[v]=d[u]+1,q.push(v);
}
}
return ~d[t];
}
int dfs(int u,int lim=INF){
if(u==t)return lim;
int flow=0;
for(int i=cur[u];i&&flow<lim;i=edge[i].nex){
cur[u]=i;
int v=edge[i].to,c=edge[i].c;
if(!c||d[v]!=d[u]+1)continue;
int f=dfs(v,min(lim-flow,c));
if(!f)d[v]=-1;
edge[i].c-=f,edge[i^1].c+=f,flow+=f;
}
return flow;
}
int dinic(){
int flow=0;
for(;bfs();)flow+=dfs(s);
return flow;
}
}
费用流
const int N=1e5+10,M=2e5+10,Inf=1e9;
namespace Flow{
const ll INF=1e18;
const int V=N,E=M*2+N*2*2;
int s,t,kk,head[V],cur[V],vis[V];
ll d[V];
struct edges{
int to,c,w,nex;
}edge[E];
void init(int x,int y){
s=x,t=y,kk=1;
fill(head+s,head+1+t,0);
}
void add(int u,int v,int c,int w){
edge[++kk]={v,c,w,head[u]},head[u]=kk;
edge[++kk]={u,0,-w,head[v]},head[v]=kk;
}
bool bfs(){
queue<int>q;
copy(head+s,head+1+t,cur+s);
fill(d+s,d+1+t,INF),d[s]=0;
q.push(s);
for(int u;!q.empty();){
u=q.front(),q.pop();
for(int i=head[u];i;i=edge[i].nex){
int v=edge[i].to,c=edge[i].c,w=edge[i].w;
if(c&&d[v]>d[u]+w){
d[v]=d[u]+w,q.push(v);
}
}
}
return d[t]<INF;
}
ll sum;
int dfs(int u,int lim=Inf){
if(u==t)return lim;
vis[u]=1;
int flow=0;
for(int i=cur[u];i&&flow<lim;i=edge[i].nex){
cur[u]=i;
int v=edge[i].to,c=edge[i].c;
if(!c||d[v]!=d[u]+edge[i].w||vis[v])continue;
int f=dfs(v,min(lim-flow,edge[i].c));
if(!f)d[v]=INF;
edge[i].c-=f,edge[i^1].c+=f,flow+=f;
sum+=1ll*f*edge[i].w;
}
vis[u]=0;
return flow;
}
int dinic(){
int flow=sum=0;
for(;bfs();)flow+=dfs(s);
return flow;
}
}
dij 费用流
const int N=5e3+10,M=5e4+10,Inf=1e9;
const ll INF=1e18;
namespace Flow{
const int V=N,E=M*2;
int s,t,kk,head[V],pre[V],vis[V];
ll d[V];
struct edges{
int to,c,w,nex;
}edge[E];
void init(int x,int y){
s=x,t=y,kk=1;
fill(head+s,head+1+t,0);
}
void add(int u,int v,int c,int w){
edge[++kk]={v,c,w,head[u]},head[u]=kk;
edge[++kk]={u,0,-w,head[v]},head[v]=kk;
}
bool spfa(){
queue<int>q;
fill(d+s,d+1+t,INF);
q.push(s),d[s]=0,vis[s]=1;
for(int u;!q.empty();){
u=q.front(),q.pop(),vis[u]=0;
for(int i=head[u];i;i=edge[i].nex){
int v=edge[i].to;
if(edge[i].c&&d[v]>d[u]+edge[i].w){
d[v]=d[u]+edge[i].w;
if(!vis[v])q.push(v),vis[v]=1;
}
}
}
return d[t]<INF;
}
ll sum,h[V];
bool dij(){
priority_queue<pair<ll,int>>q;
fill(d+s,d+1+t,INF);
q.push({d[s]=0,s});
for(int u;!q.empty();){
u=q.top().second,q.pop();
if(vis[u])continue;
vis[u]=1;
for(int i=head[u];i;i=edge[i].nex){
int v=edge[i].to;
if(!edge[i].c)continue;
if(d[v]>d[u]+h[u]-h[v]+edge[i].w){
d[v]=d[u]+h[u]-h[v]+edge[i].w;
pre[v]=i;
q.push({-d[v],v});
}
}
}
if(!vis[t])return 0;
fill(vis+s,vis+1+t,0);
return 1;
}
int EK(){
sum=0;
if(!spfa())return 0;
copy(d+s,d+1+t,h+s);
int res=0;
for(;dij();){
int flow=Inf;
for(int u=t,i;i=pre[u],u^s;u=edge[i^1].to){
flow=min(flow,edge[i].c);
}
res+=flow;
for(int u=t,i;i=pre[u],u^s;u=edge[i^1].to){
edge[i].c-=flow,edge[i^1].c+=flow,sum+=1ll*edge[i].w*flow;
}
for(int i=s;i<=t;i++)h[i]+=d[i];
}
return res;
}
}