zoukankan      html  css  js  c++  java
  • 有上下界网络流

    sgu194:

    //无源汇上下界网络流,求最大流。
    /*
    每条边add(u,v,up[i]-dn[i])
    每个点out[i]=∑dn[i,v];in[i]=∑dn[v,i];
    每个点in[i]-out[i]>0 add(s,i, in[i]-out[i]),否则add(i,t,out[i]-in[i]);
    判断与st相连的边是否满流即可。
    */

    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<algorithm>
    using namespace std;
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define clr(x,c) memset(x,c,sizeof(x))
    #define qwq(x) for(edge *o=head[x];o;o=o->next)
    int read(){
    	int x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    }
    const int nmax=205;
    const int maxn=8e4+5;
    const int inf=0x7f7f7f7f;
    struct edge{
    	int to,cap;edge *next,*rev;
    };
    edge es[maxn],*pt=es,*head[nmax];
    void add(int u,int v,int d){
    	pt->to=v;pt->cap=d;pt->next=head[u];head[u]=pt++;
    	pt->to=u;pt->cap=0;pt->next=head[v];head[v]=pt++;
    	head[u]->rev=head[v];head[v]->rev=head[u];
    }
    edge *cur[nmax],*p[nmax];
    int cnt[nmax],h[nmax];
    int maxflow(int s,int t,int n){
    	cnt[0]=n;int flow=0,a=inf,x=s;edge *e;
    	while(h[s]<n){
    		for(e=cur[x];e;e=e->next) if(e->cap>0&&h[x]==h[e->to]+1) break;
    		if(e){
    			a=min(a,e->cap);cur[x]=p[e->to]=e;x=e->to;
    			if(x==t){
    				while(x!=s) p[x]->cap-=a,p[x]->rev->cap+=a,x=p[x]->rev->to;
    				flow+=a,a=inf;
    			}
    		}else{
    			if(!--cnt[h[x]]) break;
    			h[x]=n;
    			for(e=head[x];e;e=e->next) if(e->cap>0&&h[x]>h[e->to]+1) cur[x]=e,h[x]=h[e->to]+1;
    			cnt[h[x]]++;
    			if(x!=s) x=p[x]->rev->to;
    		}
    	}
    	return flow;
    }
    int out[nmax],in[nmax],dn[maxn];
    bool work(int s,int t,int n,int m){
    	maxflow(s,t,n);
    	qwq(s) if(o->cap) return 0;
    	qwq(t) if(o->cap!=out[o->to]-in[o->to]) return 0;
    	puts("YES");
    	pt=es+1;rep(i,1,m) printf("%d
    ",dn[i]+pt->cap),pt+=2;
    	return 1;
    }
    int main(){
    	int n=read(),m=read(),u,v,d,tp;
    	rep(i,1,m){
    		u=read(),v=read(),dn[i]=read();tp=read();
    		add(u,v,tp-dn[i]);in[v]+=dn[i];out[u]+=dn[i];
    	}
    	rep(i,1,n){
    		if(in[i]-out[i]>0) add(0,i,in[i]-out[i]);
    		else add(i,n+1,out[i]-in[i]);
    	}
    	if(!work(0,n+1,n+2,m)) puts("NO");
    	return 0;
    }
    

      

  • 相关阅读:
    C. Tesla (模拟 + 思维)
    E
    E. Ehab's REAL Number Theory Problem (bfs + 思维)
    uva 12307
    P4249 [WC2007]剪刀石头布
    luoguP4003 无限之环
    luoguP4068 [SDOI2016]数字配对
    有源汇有上下界最小流
    有源汇有上下界最大流
    无源汇有上下界可行流
  • 原文地址:https://www.cnblogs.com/fighting-to-the-end/p/5881458.html
Copyright © 2011-2022 走看看