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

网络流--最大流dinic模板

2015-04-24 19:24 316 查看
标准的大白书式模板,除了变量名并不一样……在主函数中只需要用到 init 函数、add 函数以及 mf 函数

#include<stdio.h>                //差不多要加这么些头文件
#include<string.h>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;
const int maxm=150+5;        //点的总数
const int INF=0x3f3f3f3f;

struct edge{             //弧的结构体,变量:弧的出发点、结束点、容量、流量
int from,to,c,f;
edge(int a,int b,int m,int n):from(a),to(b),c(m),f(n){}
};

struct dinic{
int m,s,t;                    //边数、源点标号、汇点标号
vector<edge>e;        //边
vector<int>g[maxm];    //g[i][j]表示第i个点出发的第j条边在e中的编号
bool vis[maxm];
int d[maxm],cur[maxm];    //d为源点到点的距离,cur为当前遍历到的边
void init(int n){                //初始化,n为点数量(标号0~n-1)
for(int i=0;i<n+5;i++)g[i].clear();
e.clear();
}
void add(int a,int b,int v){        //加入弧和反向弧
e.push_back(edge(a,b,v,0));    //正向弧容量v,反向弧容量0
e.push_back(edge(b,a,0,0));
m=e.size();
g[a].push_back(m-2);
g[b].push_back(m-1);
}
bool bfs(){
memset(vis,0,sizeof(vis));
queue<int>q;
q.push(s);
d[s]=0;
vis[s]=1;
while(!q.empty()){
int u=q.front();q.pop();
for(int i=0;i<g[u].size();i++){
edge tmp=e[g[u][i]];
if(!vis[tmp.to]&&tmp.c>tmp.f){
vis[tmp.to]=1;
d[tmp.to]=d[u]+1;
q.push(tmp.to);
}
}
}
return vis[t];
}
int dfs(int x,int a){
if(x==t||a==0)return a;
int flow=0,f;
for(int& i=cur[x];i<g[x].size();i++){
edge &tmp=e[g[x][i]];
if(d[x]+1==d[tmp.to]&&(f=dfs(tmp.to,min(a,tmp.c-tmp.f)))>0){
tmp.f+=f;
e[g[x][i]^1].f-=f;
flow+=f;
a-=f;
if(a==0)break;
}
}
if(!flow)d[x]=-1;
return flow;
}
int mf(int s,int t){                //在主函数中使用的函数,求s到t的最大流
this->s=s;
this->t=t;
int flow=0;
while(bfs()){
memset(cur,0,sizeof(cur));
flow+=dfs(s,INF);
}
return flow;
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: