zoukankan      html  css  js  c++  java
  • LOJ.117.[模板]有源汇有上下界最小流(Dinic)

    题目链接

    有源汇有上下界最小流
    Sol1. 首先和无源汇网络流一样建图,求SS->TT最大流;
    然后连边(T->S,[0,INF]),再求一遍SS->TT最大流,答案为新添加边的流量
    无解情况: 连边后再求最大流+之前的最大流 != ∑dgr
    解释: 第一次最大流已经满足下界,满足下界的情况下能流的边已尽量流满
    那么残量网络的最大流就会尽可能小了

    Sol2. 首先和无源汇网络流一样建图,然后连边(T->S,[0,INF]),求SS->TT的最大流okflow
    然后删去T->S的这条边,求T->S的最大流mn,则答案为okflow-mn
    解释: 第一次是求可行流,使其满足流量下界;
    第二次利用 反向弧流量的增加=正向边流量的减少,由T->S的最大流就是S->T最大能减少的流量(满足可行流)

    #include<cstdio>
    #include<cctype>
    #include<algorithm>
    #define gc() getchar()
    typedef long long LL;
    const int N=5e4+9,M=125009+N;
    const LL INF=1e14;
    
    int n,m,src,des,Enum,H[N],nxt[M<<1],to[M<<1],lev[N],cur[N],q[N],dgr[N];
    LL cap[M<<1];
    
    inline LL read()
    {
    	LL now=0;register char c=gc();
    	for(;!isdigit(c);c=gc());
    	for(;isdigit(c);now=now*10+c-'0',c=gc());
    	return now;
    }
    inline void AddEdge(int u,int v,LL w)
    {
    	to[++Enum]=v, nxt[Enum]=H[u], H[u]=Enum, cap[Enum]=w;
    	to[++Enum]=u, nxt[Enum]=H[v], H[v]=Enum, cap[Enum]=0;
    }
    bool BFS()
    {
    	for(int i=0;i<=n+1;++i) lev[i]=0,cur[i]=H[i];
    	lev[src]=1, q[0]=src;
    	int h=0,t=1;
    	while(h<t)
    	{
    		int x=q[h++];
    		for(int i=H[x];i;i=nxt[i])
    			if(!lev[to[i]]&&cap[i])
    			{
    				lev[to[i]]=lev[x]+1, q[t++]=to[i];
    				if(to[i]==des) return 1;
    			}
    	}
    	return 0;
    }
    LL Dinic(int u,LL flow)
    {
    	if(u==des) return flow;
    	LL used=0;
    	for(int &i=cur[u];i;i=nxt[i])
    		if(lev[to[i]]==lev[u]+1 && cap[i])
    		{
    			LL delta=Dinic(to[i],std::min(cap[i],flow-used));
    			if(delta)
    			{
    				cap[i]-=delta, cap[i^1]+=delta, used+=delta;
    				if(used==flow) return flow;
    			}
    		}
    	lev[u]=0;
    	return used;
    }
    
    int main()
    {
    	Enum=1;
    	n=read(),m=read();int s=read(),t=read(),ss=0,tt=n+1;
    	LL low,upp,sum=0,okflow=0;
    	for(int u,v,i=1;i<=m;++i)
    	{
    		u=read(),v=read(),low=read(),upp=read(),
    		dgr[u]-=low,dgr[v]+=low, AddEdge(u,v,upp-low);
    	}
    	for(int i=1;i<=n;++i)
    		if(dgr[i]>0) AddEdge(ss,i,dgr[i]),sum+=dgr[i];
    		else if(dgr[i]<0) AddEdge(i,tt,-dgr[i]);
    	src=ss, des=tt;
    	while(BFS()) okflow+=Dinic(src,INF);
    	AddEdge(t,s,INF);
    	while(BFS()) okflow+=Dinic(src,INF);
    	if(okflow==sum) printf("%lld",cap[Enum]);
    	else printf("please go home to sleep");
    
    	return 0;
    }
    
  • 相关阅读:
    Django文档翻译:模型参考(Model Reference)
    Anthem.NET 的 "BAD RESPONSE" 问题的脚本调试技巧小结
    注意 JavaScript 中 RegExp 对象的 test 方法
    CodeProject 文章收藏 (200713)
    Django 学习纪要(1) 模版语法
    关注一下 IronPython Community Edition
    SubSonic 的字段名未转义问题修正
    Error while trying to run project: Unable to start debugging 绑定句柄无效
    Django 中自定义 tag 如何获取变量参数的值
    Karrigell 初次学习
  • 原文地址:https://www.cnblogs.com/SovietPower/p/8416624.html
Copyright © 2011-2022 走看看