zoukankan      html  css  js  c++  java
  • 有源汇有上下界的最小流(LOJ117)

    一个有源汇有上下界的最小流的瞎那啥讲解

    其实最小流和最大流个人感觉很类似,连接了超级源点和超级汇点之后跑完一次最大流,一个是再在除去超级源点和超级汇点跑一次最大流,一个是给源汇点连一个无限边求最大流,然后无限边的流量就是答案

    因为一个相当于是要把残量网络剩下的流加起来,才是最大流,而这个跑过最大流后剩下的就是最小流了

    当然必须要当前弧优化,否则跑不过去

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define re register 
    const ll inf=1e15;
    int str,des,cnt=1,adj[50050],tp[50050],nxt[500050],to[500050],lev[50050],low[500050],st,de,m,n;
    ll def[50050],cap[500050];
    inline int read(){
    	char ch;
    	while((ch=getchar())<'0'||ch>'9'){;}
    	int res=ch-'0';
    	while((ch=getchar())>='0'&&ch<='9')
    	res=res*10+ch-'0';
    	return res;
    }
    inline void addedge(int u,int v,long long p)
    {
    	nxt[++cnt]=adj[u],adj[u]=cnt,to[cnt]=v,cap[cnt]=p;
    	nxt[++cnt]=adj[v],adj[v]=cnt,to[cnt]=u,cap[cnt]=0;
    }
    inline bool bfs(){
    	int u,e,v;
    	queue<int> que;
    	memset(lev,-1,sizeof(lev));
    	que.push(str),lev[str]=0;
    	while(!que.empty())
    	{
    		u=que.front(),que.pop();
    		for(int e=adj[u];e;e=nxt[e])
    		{
    			if(cap[e]>0&&lev[v=to[e]]==-1)
    			{
    				lev[v]=lev[u]+1,que.push(v);
    				if(v==des) return true;
    			}
    		}
    	}
    	return false;
    }
    inline long long dinic( int u,ll flow)
    {
    	if(u==des) return flow;
    	ll res=0,flw;
    	int v;
    	for(int &e=tp[u];e&&res<=flow;e=nxt[e])
    	{
    		if(cap[e]>0&&lev[u]+1==lev[v=to[e]])
    		{
    	  	int minn=dinic(v,min(flow-res,cap[e]));
    	  	cap[e]-=minn,cap[e^1]+=minn,res+=minn;
    	  	if(flow==res) return res;
    		}
    	}
    	return lev[u]=0,res;
    }
    inline long long  solve(){
    	long long ans=0;
    	while(bfs()==true) {
    		memcpy(tp,adj,sizeof(adj));
    		ans+=dinic(str,inf);
    	}
    	return ans;
    }
    int main(){
    	n=read(),m=read(),st=read(),de=read();
    	int s,t;
    	ll up,down;
    	long long sum=0;
    	for(re int i=1;i<=m;i++)
    	{
    		s=read(),t=read(),down=read(),up=read();
    		addedge(s,t,up-down);
    		low[i]=down,def[s]+=down,def[t]-=down;
    	}
    	str=0,des=n+1;
    	for(re int i=1;i<=n;i++)
    	{
    		if(def[i]>0) addedge(i,des,def[i]);
    		if(def[i]<0) addedge(str,i,-def[i]);
    	}
    	sum=solve();
    	addedge(de,st,inf);
    	sum+=solve();
    	for(re int e=adj[des];e;e=nxt[e]) 
    	{
    		if(cap[e^1]>0)
    		{
    			cout<<"please go home to sleep"<<'
    ';
    			return 0;
    		}
    	}
    	cout<<cap[cnt];
    	return 0;
    }
    
  • 相关阅读:
    什么是Code Review
    支撑5亿用户、1.5亿活跃用户的Twitter最新架构详解及相关实现
    shell的数组操作
    CDN(内容分发网络)技术原理
    云计算服务模型,第 3 部分: 软件即服务(PaaS)
    Mongodb
    360的开源项目
    用linux mail命令发送邮件[Linux]
    BZOJ2761:[JLOI2011]不重复数字(map)
    BZOJ1821:[JSOI2010]部落划分(并查集,二分)
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/10366516.html
Copyright © 2011-2022 走看看