Skip to content

Commit

Permalink
Update 最大流.md
Browse files Browse the repository at this point in the history
板子加上当前弧优化
  • Loading branch information
CurryWOE authored Oct 30, 2023
1 parent 93576d4 commit 36437f6
Showing 1 changed file with 44 additions and 53 deletions.
97 changes: 44 additions & 53 deletions docs/Graph/最大流.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ $O(V^2E)$,如果用在二分图,是 $O(E\sqrt V)$
二分图最小路径覆盖=原图节点数-最大匹配.
## 板子
```c++
const int N=2e2+5;
const int N=3.2e3;
const int M=1e6+3;
const ll INF=1e18;
namespace Dinic
Expand All @@ -50,67 +50,38 @@ namespace Dinic
{
int v,nxt;
ll cap;
};
int n,s,t,tot;
int head[N],dep[N];
Edge e[M];
}e[M];
int n,s,t,tot,hd[N],dep[N],cur[N];
queue<int> q;
void init(int nn,int ss,int tt)
void init(int nn)
{
n=nn;
s=ss;
t=tt;
memset(head,0,sizeof(int)*(n+1));
head[s]=head[t]=0;
n=nn,s=nn+1,t=nn+2;
memset(hd,0,sizeof(int)*(n+3));
tot=1;
}
void addEdge(int x,int y,ll cap)
{
e[++tot]={y,head[x],cap};
head[x]=tot;
e[++tot]={x,head[y],0};
head[y]=tot;
}
bool level()
{
memset(dep,0,sizeof(int)*(n+1));
dep[t]=0;
dep[s]=1;
int u,v;
q.push(s);
while(!q.empty())
{
u=q.front();
q.pop();
for(int i=head[u];i;i=e[i].nxt)
{
v=e[i].v;
if(e[i].cap && !dep[v])
{
dep[v]=dep[u]+1;
q.push(v);
}
}
}
return dep[t];
e[++tot]={y,hd[x],cap};
hd[x]=tot;
e[++tot]={x,hd[y],0};
hd[y]=tot;
}
ll findpath(int u,ll in)
{
if(u==t)
return in;
ll out=0,res;
int v;
for(int i=head[u];i && in;i=e[i].nxt)
ll out=0;
for(int i=cur[u];i && in;i=e[i].nxt)
{
v=e[i].v;
if(e[i].cap && dep[v]==dep[u]+1)
{
res=findpath(v,min(in,e[i].cap));
e[i].cap-=res;
e[i^1].cap+=res;
out+=res;
in-=res;
}
cur[u]=i;
int v=e[i].v;
if(!e[i].cap || dep[v]!=dep[u]+1)
continue;
ll res=findpath(v,min(in,e[i].cap));
e[i].cap-=res;
e[i^1].cap+=res;
out+=res;
in-=res;
}
if(!out)
dep[u]=0;
Expand All @@ -119,12 +90,32 @@ namespace Dinic
ll dinic()
{
ll res=0;
while(level())
while(1)
{
memset(dep,0,sizeof(int)*(n+3));
memcpy(cur,hd,sizeof(int)*(n+3));
dep[s]=1;
q.push(s);
while(!q.empty())
{
int u=q.front();
q.pop();
for(int i=hd[u];i;i=e[i].nxt)
{
int v=e[i].v;
if(!e[i].cap || dep[v])
continue;
dep[v]=dep[u]+1;
q.push(v);
}
}
if(!dep[t])
return res;
res+=findpath(s,INF);
return res;
}
}
};
Dinic::init(n,s,t);
Dinic::init(n);//源点为n+1,汇点为n+2
Dinic::addEdge(u,v,w);//边的顺序一定是源点-中间点-汇点
Dinic::dinic();
```

0 comments on commit 36437f6

Please sign in to comment.