dinic最大流模板(最小割)

时间:2022-02-15 15:31:15

hdu1532

题目链接:

http://acm.split.hdu.edu.cn/showproblem.php?pid=1532

思路:

建立邻接表,直接求解最大流。

代码:

#include <bits/stdc++.h>
using namespace std;
#define maxn 1100 //顶点的最大值
#define INF 0xfffffff
int deep[maxn],N,M,cnt,head[maxn]; //N是顶点数
int s,t; //源点汇点
struct Edge
{
int v,cap;
int next;
}edge[maxn*maxn];//邻接表

int bfs()
{
memset(deep,-1,sizeof(deep));
queue<int>q;
q.push(s);
deep[s]=0;
while(!q.empty())
{
int now=q.front();
q.pop();
for(int nex=head[now];nex!=-1;nex=edge[nex].next)
{
if(deep[edge[nex].v]==-1&&edge[nex].cap>0)
{
deep[edge[nex].v]=deep[now]+1;
q.push(edge[nex].v);
}
}
}
if(deep[t]==-1) return 0;
return 1;
}

int Min(int a,int b)
{
return a<b?a:b;
}

int dfs(int pos,int flow)
{
if(pos==t) return flow;
int t=0,sum=0;
for(int nex=head[pos];nex!=-1;nex=edge[nex].next)
{
if(deep[edge[nex].v]==deep[pos]+1&&edge[nex].cap>0)
{
t=dfs(edge[nex].v,Min(flow-sum,edge[nex].cap));
if(t>0)
{
edge[nex].cap-=t;
edge[nex^1].cap+=t;
sum+=t;
if(sum==flow) break;
}
else deep[edge[nex].v]=-1;
}
}
return sum;//当前点可增广的最大流量
}
int dinic() //最大流
{
int sum=0;
while(bfs())
sum+=dfs(s,INF);
return sum;
}
void add(int u,int v,int w) //加边
{
//u->v
edge[cnt].v=v;
edge[cnt].cap=w;
edge[cnt].next=head[u];
head[u]=cnt++;
//v->u
edge[cnt].v=u;
edge[cnt].cap=0;
edge[cnt].next=head[v];
head[v]=cnt++;
}

void init()//初始化函数,不要忘记加
{
memset(head,-1,sizeof(head));//初始化邻接表
s=1;cnt=0;//源点汇点以及cnt的初始化
t=N;
}
int main()
{
while(~scanf("%d%d",&M,&N)){
init();
for(int i=1;i<=M;i++){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);
}
printf("%d\n",dinic());
}
}