码迷,mamicode.com
首页 > 其他好文 > 详细

网络流(自行理解的Dinic)

时间:2017-12-25 00:58:37      阅读:151      评论:0      收藏:0      [点我收藏+]

标签:统计   i++   const   amp   找不到   死循环   bit   main   网络流   

#include<bits/stdc++.h>
const int maxn=100008;
using namespace std;
int read()
{
char ch=getchar();int f=1,w=0;
while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
while(ch<=‘9‘&&ch>=‘0‘){w=w*10+ch-‘0‘;ch=getchar();}
return f*w;
} //读入优化

struct sj{
int next;
int to;
int w; //w是剩余的流量
}a[maxn*2];
int head[maxn],size=1; //注意size 要赋值为1 否则会死循环
int m,n;
int s,t;
int cent[maxn]; //层数
int ans;

void add(int x,int y,int z)
{
a[++size].to=y;
a[size].next=head[x];
head[x]=size;
a[size].w=z;
} //加边

bool bfs()
{
memset(cent,-1,sizeof(cent)); //cent 层数先清零
queue <int> q;
q.push(s);
cent[s]=0; //起点进栈
while(q.empty()!=1)
{
int ks=q.front();
q.pop();
for(int i=head[ks];i;i=a[i].next)
{
int ts=a[i].to;
if(cent[ts]==-1&&a[i].w>0)
{
q.push(ts);
cent[ts]=cent[ks]+1; //层数加1
}
}
}
if(cent[t]<0) //如果已经找不到增广路
return 0;
return 1;
}

int dfs(int x,int low) //dfs搜索 参数:当前的点,当前最小的流量
{
if(x==t)return low; //如果已经搜到终点了 就直接返回
int flow=0,r; //避免重复流 每次都新定义一个统计的流量 每层都各自求和
for(int i=head[x];i;i=a[i].next)
{
int st=a[i].to;
if((a[i].w>0)&&(cent[st]==cent[x]+1))
{
r=dfs(st,min(a[i].w,low-flow)); //递归在这里
if(r>0)
{
a[i].w-=r; //当前增广路走过的边 残量减掉这么多
a[i^1].w+=r; //反向边则加上这么多
flow+=r; //流量加上r 这次找已经流了这么多
}
}
}
return flow; //递归返回时 则返回已经流完的流量
}


int main() //主函数
{
n=read();m=read();
s=read();t=read();
for(int i=1;i<=m;i++)
{
int x,y,z;
x=read();
y=read();
z=read();
add(x,y,z);
add(y,x,0);
} //建立反向边
while(bfs())
{
int row=dfs(s,0x3f3f3f); //row代表这次搜索找到的流量总和
ans+=row;
cout<<row<<endl;
} //还能找到增广路
cout<<ans;
return 0;
}

网络流(自行理解的Dinic)

标签:统计   i++   const   amp   找不到   死循环   bit   main   网络流   

原文地址:http://www.cnblogs.com/Kv-Stalin/p/8099374.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!