首页 > 代码库 > 网络最大流 dinic算法

网络最大流 dinic算法

一句话题意:给出一个网络图,以及其源点和汇点,求出其网络最大流

//dinic算法;//时间复杂度O(V^2E); #include<bits/stdc++.h>#define inf 999999#define maxn 200000using namespace std;int n,m,s,t;int ans=0;struct Edge{   int to,next,w;};struct Edge edge[maxn];int head[maxn],val[maxn],pre[maxn];int level[maxn];int cnt=0;void add(int u,int v,int w)//前向星储存边 {    edge[cnt].to=v;    edge[cnt].w=w;    edge[cnt].next=head[u];    head[u]=cnt++;}int bfs(int s,int t){    queue<int> q;    q.push(s);	memset(level,-1,sizeof(level));//一定要从-1开始储存,如果从0开始存的话由于数组本身就是0,会造成死循环!! 	level[s]=0;   while(!q.empty())   {     int j=q.front();q.pop();     for(int i=head[j];~i;i=edge[i].next)     {	    int v=edge[i].to;	    if(level[v]==-1&&edge[i].w)//染色,广搜求出到达每个点的步数 	    {		   level[v]=level[j]+1;		   q.push(v);		}	 }   }   return (level[t]==-1) ? 0 : 1;//如果不能达到t就是没有增广路,就不进行查找 }int dfs(int u,int flow,int v){	  if(u==v)	    return flow;	  int rest=0;	  for(int i=head[u];~i;i=edge[i].next)	  {	     int j=edge[i].to;	     if(level[u]+1==level[j]&&edge[i].w)	     {		     int flo=dfs(j,min(edge[i].w,flow-rest),v);     		     rest+=flo;			 edge[i].w-=flo;		     edge[i^1].w+=flo;//如果i=0,则去i+1如果i=1则取0,总之是取反向边 		 }	  }	  if(!rest)	    level[u]=-1;	  return rest;}int main(){	int u,v,w;	memset(head,-1,sizeof(head)); 	cin>>n>>m>>s>>t;	for(int i=0;i<m;i++)//注意从0开始储存,否则会发生错误 	{	   cin>>u>>v>>w;	   add(u,v,w);//s->t存到2k	   add(v,u,0);//t->s存到2k-1 	}	while(bfs(s,t))	   while(int tmp=dfs(s,inf,t))	     ans+=tmp;	cout<<ans<<endl;    return 0;}

 

网络最大流 dinic算法