您的位置:首页 > 理论基础 > 计算机网络

网络流DINIC递归版模版

2015-08-03 09:55 423 查看
PS:http://blog.csdn.net/qq574857122/article/details/20659275

#include<iostream>

#include<cstdio>

#include<string.h>

#include<string>

#include<stack>

#include<set>

#include<algorithm>

#include<cmath>

#include<vector>

#include<map>

#include<sstream>

#include<queue>

#define ll __int64

#define lll unsigned long long

#define MAX 1000009

#define MAXN 2009

#define eps 1e-8

#define INF 0x7fffffff

#define mod 1000000007

#define clr(a) memset(a,0,sizeof(a))

#define clr1(a) memset(a,-1,sizeof(a))

#define lson l , m , rt << 1

#define rson m + 1 , r , rt << 1 | 1

using namespace std;

inline ll Max(ll a,ll b)

{

return a>b?a:b;

}

inline ll Min(ll a,ll b)

{

return a<b?a:b;

}

const int N = 100000;

const int M = 100000;

struct Edge

{

int from,to,flow,cap, nex;

} edge[M*2]; //双向边,注意RE的情况 注意这个模版是 相同起末点的边 合并流量

int head
,edgenum;//2个要初始化-1和0

void addedge(int u,int v,int cap) //网络流要加反向弧

{

Edge E= {u,v,0,cap,head[u]};

edge[edgenum]=E;

head[u]=edgenum++;

Edge E2= {v,u,0,0,head[v]}; //这里的cap若是单向边要为0

edge[edgenum]=E2;

head[v]=edgenum++;

}

int dis
,cur
;//距离起点的距离 cur[i]表示i点正在考虑的边 优化不再考虑已经用过的点 初始化为head

bool vis
;

bool BFS(int Start,int End)

{

memset(vis,0,sizeof(vis));

memset(dis,-1,sizeof(dis));

queue<int>Q;

while(!Q.empty())Q.pop();

Q.push(Start);

dis[Start]=0;

vis[Start]=1;

while(!Q.empty())

{

int u = Q.front();

Q.pop();

for(int i=head[u]; i!=-1; i=edge[i].nex)

{

Edge& E =edge[i];

if(!vis[E.to] && E.cap>E.flow)

{

vis[E.to]=1;

dis[E.to]=dis[u]+1;

if(E.to==End)return true;

Q.push(E.to);

}

}

}

return false;

}

int DFS(int x, int a,int End) //流入x 的流量是a

{

if(x==End || a==0)return a;

int flow = 0, f;

for(int& i=cur[x]; i!=-1; i=edge[i].nex)

{

Edge& E = edge[i];

if(dis[x]+1 == dis[E.to] && (f = DFS(E.to , Min(a, E.cap-E.flow), End))>0 )

{

E.flow += f;

edge[ i^1 ].flow -= f;//反向边要减掉

flow += f;

a -= f;

if(a==0)break;

}

}

return flow;

}

int Dinic(int Start,int End)

{

int flow=0;

while(BFS(Start,End))

{

memcpy(cur,head,sizeof(head));//把head的数组复制过去

flow += DFS(Start, INF , End);

//cout<<flow<<" "<<Start<<" "<<End<<endl;

}

return flow;

}

void init()

{

memset(head, -1, sizeof(head));

edgenum = 0;

}

int main()

{

#ifdef ONLINE_JUDGE

#else

freopen("an.txt","r", stdin);

#endif

int m,n;

while(~scanf("%d%d",&m,&n))

{

int u,v,w;

init();

for(int i = 0; i<m; i++)

{

scanf("%d%d%d",&u,&v,&w);

addedge(u,v,w);

}

cout<<Dinic(1,n)<<endl;

}

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: