【模板】网络流

1.边从2标号算起,j和j^1互为反边。
 
2.棋盘一般都是二分图模型,连边注意方向!
 
3.分配限制用最大流卡流,取舍限制用最小割决策。
 

常见模型:最大匹配模型、最小割模型、最小路径覆盖模型

有时候需要配合二分。



Code:

#include<cstdio>
#include<algorithm>
using namespace std;
const int Sn = 10010, Sm = 1000010 *2, oo = (int)1e9;

int n,m,s,t,la[Sn],to[Sm],nx[Sm],rs[Sm],fy[Sm],dn,bn=1;
int ln[Sn],l,r,vis[Sn],V,hei[Sn],top;
int next[Sn],hd,tl,tmp,dis[Sn],il[Sn],pp[Sn],pre[Sn];
int maxflow,totfy;

void link(int u, int v, int w)
{
     bn++, to[bn] = v, rs[bn] = w, nx[bn] = la[u], la[u] = bn;
     bn++, to[bn] = u, rs[bn] = 0, nx[bn] = la[v], la[v] = bn;
}
bool bfs()
{
     vis[t] = ++V, hei[t] = 1;
     for(ln[l=r=1] = t; l <= r; l++)
	  for(int j = la[ln[l]]; j; j = nx[j])
	       if(rs[j^1] && vis[to[j]] != V)
	       {
		    hei[to[j]] = hei[ln[l]] + 1, vis[to[j]] = V;
		    ln[++r] = to[j]; if(to[j] == s) return true;
	       }
     return false;
}
int dfs(int d, int p)
{
     int flow = 0, f;
     if(d == t || p == 0) return p;
     for(int j = la[d]; j; j = nx[j])
	  if(vis[to[j]] == V && hei[to[j]] == hei[d] - 1)
	       if(rs[j] && ( f = dfs(to[j], min(p,rs[j])) ) > 0)
	       {
		    rs[j] -= f, rs[j^1] += f;
		    flow += f, p -= f;
		    if(!p) return flow;
	       }
     hei[d] = oo;
     return flow;
}
bool spfa()
{
     for(int i = 1; i <= dn; i ++) dis[i] = oo;
     dis[s] = 0, pp[s] = oo; // WA
     for(il[hd=tl=s] = true; hd; tmp=hd, hd=next[hd], next[tmp]=il[tmp]=0)
	  for(int j = la[hd], o; j; j = nx[j])
	       if(rs[j] && (o = dis[hd] + fy[j]) < dis[to[j]] && o <= dis[t])
	       {
		    dis[to[j]] = dis[hd] + fy[j], pp[to[j]] = min(pp[hd], rs[j]);
		    pre[to[j]] = j ^ 1;
		    if(!il[to[j]]) {
			 if(hd != tl && dis[to[j]] < dis[next[hd]]) next[to[j]] = next[hd], next[hd] = to[j];
			 else next[tl] = to[j], tl = to[j];  il[to[j]] = true; }
	       }
     if(dis[t] == oo) return false;
     for(int j = t; j != s; j = to[pre[j]])
	  rs[pre[j]^1] -= pp[t], rs[pre[j]] += pp[t];
     totfy += dis[t] * pp[t], maxflow += pp[t];
     return true;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值