图论算法-网络最大流模板【EK;Dinic】
EK模板
每次找出增广后残量网络中的最小残量增加流量
const int inf=1e9;
int n,m,s,t;
struct node{int v,cap;};
vector<node> map[100010];
int flow[10010][10010];
int a[100010];
int pre[100010];
int EK()
{
int maxf;//记录最大流量
queue<int> q;
while(1)
{
memset(a,0,sizeof(a));
a[s]=inf;
q.push(s);
while(!q.empty())
{
int u=q.front();
q.pop();
for(int j=0;j<map[u].size();j++)
{
int v=map[u][j].v;
int cap=map[u][j].cap;
if(!a[v]&&cap>flow[u][v])
{
pre[v]=u;
q.push(v);
a[v]=min(a[u],cap-flow[u][v]);
}
}
}
if(a[t]==0)
break;
for(int u=t;u!=s;u=pre[u])
{
flow[ pre[u] ][u]+=a[t];
flow[ u][ pre[u] ]-=a[t];
}
maxf+=a[t];
}
return maxf;
}
int main()
{
cin>>n>>m>>s>>t;
for(int i=1;i<=m;i++)
{
int u,v,dis;
cin>>u>>v>>dis;
map[u].push_back((node) {v,dis });
map[v].push_back((node) {u,0 });//**高亮**反向边一定要记得建
}
int ans=EK();
cout<<ans;
return 0;
}
Dinic模板
构造层次+阻塞流增广
const int inf=1e9;
int n,m;
int s,t;
int tot=1;
struct node{int v,f,nxt;}E[1000010];
int head[100010];
int lev[100010];//记录层次
void add(int u,int v,int cap)
{
E[++tot].v=v;
E[tot].nxt=head[u];
E[tot].f=cap;
head[u]=tot;
}
bool bfs()
{
queue<int> q;
memset(lev,-1,sizeof(lev));
q.push(s);
lev[s]=0;
while(!q.empty())
{
int u=q.front();
q.pop();
for(int i=head[u];i;i=E[i].nxt)
{
int v=E[i].v;
if(lev[v]==-1&&E[i].f)
{
lev[v]=lev[u]+1;
if(v==t)
return true;
q.push(v);
}
}
}
return false;
}
int dfs(int u,int cap)
{
if(u==t)
return cap;
int flow=cap;
for(int i=head[u];i;i=E[i].nxt)
{
int v=E[i].v;
if(lev[v]==lev[u]+1&&flow&&E[i].f>0)
{
int f=dfs(v,min(flow,E[i].f));
flow-=f;
E[i].f-=f;
E[i^1].f+=f;
}
}
return cap-flow;
}
int dinic()
{
int maxf=0;
while(bfs())//若s-t可达就不断构造层次图
maxf+=dfs(s,inf);//s-t可达,用阻塞流增广
return maxf;
}
int main()
{
cin>>n>>m>>s>>t;
for(int i=1;i<=m;i++)
{
int u,v,w;
cin>>u>>v>>w;
add(u,v,w);
add(v,u,0);//**高亮**反向边一定要记得建
}
dinic();
cout<<maxf;
return 0;
}