网络流基础模板
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了网络流基础模板相关的知识,希望对你有一定的参考价值。
//网络流dinic //最大流=最小割 //基本建模 //建源汇,向每个点分别连所限制的边权,题目所给的边连inf int cnt=1; inline void insert(int u,int v,int w) { e[++cnt].to=v; e[cnt].next=head[u]; head[u]=cnt; e[cnt].f=w; } inline void insert(int u,int v,int w) { insert1(u,v,w); insert1(v,w,0); } inline int dfs(int now,int f) { if(now==t) return f; for(int i=head[now];i && f;i=e[i].next) { if(e[i].f && dep[e[i].to]==dep[now]+1) { int d=dfs(e[i].to,min(e[i].f,f)); f-=d;ret+=d;e[i].f-=d;e[i^1].f+=d; } } if(!ret) dep[now]=-1; return ret; } inline bool bfs() { memset(dep,0,sizeof(dep)); q.push(s),dep[s]=1; queue<int> q; while(!q.empty()) { int now=q.front();q.pop(); for(int i=head[now];i;i=e[i].next) if(e[i].f && !dep[e[i].to]) dep[e[i].to]=dep[now]+1,q.push(e[i].to); } return dep[t]; } inline int dinic() { int ret=0; while(bfs()) ret+=dfs(s,1e9+7); return ret; } //二分图 //建立超级源汇,连边权为1,最大流 //最大匹配=最大流 //最大匹配=最小顶点覆盖 //最大点独立集=最小边覆盖 //最大匹配+最小边覆盖=最大点独立集+最小顶点覆盖=|V| //最大权闭合子图 //正点权和-最小割 //二分图点权最大点独立集 //点权和-最小割 //点限制的网络流 //拆点x0为x1->x2边权为x0的点限制 //费用流 inline int dfs(int now,int f) { if(now==t) { ans+=f*dis[t]; return f; } mark[now]=1; int ret=0; for(int i=head[now];i && f;i=e[i].next) { if(e[i].f && dis[now]+e[i].cost==dis[e[i].to] && !mark[e[i].to]) { int d=dfs(e[i].to,min(f,e[i].f)); e[i].f-=d; e[i^1].f+=d; ret+=d; f-=d; } } return ret; } inline bool spfa() { for(int i=0;i<=n+1;i++) dis[i]=inf; memset(vis,0,sizeof(vis)); memset(mark,0,sizeof(mark)); q.push(s);vis[s]=1;dis[s]=0; while(!q.empty()) { int now=q.front();q.pop();vis[now]=0; for(int i=head[now];i;i=e[i].next) { if(e[i].f && dis[now]+e[i].cost<dis[e[i].to]) { dis[e[i].to]=dis[now]+e[i].cost; if(!vis[e[i].to]) { q.push(e[i].to); vis[e[i].to]=1; } } } } return dis[t]<inf; } inline void insert(int u,int v,int f,int w) { insert1(u,v,f,w); insert1(v,u,0,-w); } inline int dinic() { ans=0; while(spfa()) dfs(s,inf); return ans; } //建图才是最难滴
以上是关于网络流基础模板的主要内容,如果未能解决你的问题,请参考以下文章