zoukankan      html  css  js  c++  java
  • Codeforces708D Incorrect Flow

    反向边的技巧还是非常不错的……

    核心技巧:减少流量当成 (v_i o u_i) 连边,同时增加就是把费用多增加一些

    首先初始的边显然要连上 ((u_i,v_i,[f_i,f_i])),因为一定要流,费用置为 (-inf) 即可

    • 如果 (c_ile f_i)

    那么首先要补到 (f_i),答案加上 (f_i-c_i)

    如果增加流量,两个得要一起来,连边 ((u_i,v_i,inf,2))

    如果在原来的 ([c_i,f_i]) 范围内减少流量,不需要付出额外的费用,连边 ((v_i,u_i,f_i-c_i,0))

    如果还要减少,费用为 (1) ,因为这时候不需要减少上限了,直接减少流量即可

    • 反之

    先补到 (c_i) 的费用只是 (1),那么连 ((u_i,v_i,c_i-f_i,1)),继续就是 ((u_i,v_i,inf,2))

    往下删和上面也是一样的, 但是不需要付出两份代价,删除也是有限度的,也就是 ((v_i,u_i,c_i,1))

    最后上个最小费用最大流

    注意:

    一开始给加入的边费用为负即可,而且负的尽量小

    否则会爆运算

    Code

    #include<bits/stdc++.h>
    using namespace std;
    #define int long long 
    #define reg register
    #define inf 1e18
    namespace yspm{
        inline int read(){
            int res=0,f=1; char k;
            while(!isdigit(k=getchar())) if(k=='-') f=-1;
            while(isdigit(k)) res=res*10+k-'0',k=getchar();
            return res*f;
        }
        const int E=4e3+10,N=1010;
        struct node{int to,nxt,lim,cst;}e[E<<1];
        int head[N],cnt=1,d[N],ct,incf[N],pre[N],n,ans,S,T,m; bool vis[N]; queue<int> q;
        inline void adde(int u,int v,int w,int c){
            e[++cnt].to=v; e[cnt].nxt=head[u]; e[cnt].lim=w; e[cnt].cst=c; 
            return head[u]=cnt,void();
        }
        inline int min(int x,int y){return x<y?x:y;}
        inline void add(int u,int v,int w,int c){return adde(u,v,w,c),adde(v,u,0,-c);}
        inline bool spfa(){
            for(reg int i=1;i<=n+2;++i) d[i]=inf; d[S]=0; incf[S]=inf; q.push(S); vis[S]=1;
            while(q.size()){
                int fr=q.front(); vis[fr]=0; q.pop(); 
                for(reg int i=head[fr];i;i=e[i].nxt){
                    int t=e[i].to; if(!e[i].lim||d[fr]+e[i].cst>=d[t]) continue;
                    d[t]=d[fr]+e[i].cst; pre[t]=i; incf[t]=min(incf[fr],e[i].lim); 
                    if(!vis[t]) vis[t]=1,q.push(t); 
                }
            } return d[T]!=inf;
        }
        inline void EK(){
            while(spfa()){
                int x=T; while(x!=S) e[pre[x]].lim-=incf[T],e[pre[x]^1].lim+=incf[T],x=e[pre[x]^1].to;
                ans+=incf[T]*d[T];   
            } return printf("%lld
    ",ans),void();
        }
        signed main(){
            n=read(); m=read(); S=n+1; T=S+1;
            for(reg int i=1,u,v,f,c;i<=m;++i){
                u=read(); v=read(); c=read(); f=read();
                add(S,v,f,-1e5); add(u,T,f,-1e5); ans+=f*2e5;
                if(f<=c) add(u,v,c-f,1),add(u,v,inf,2),add(v,u,f,1); 
                else ans+=f-c,add(v,u,c,1),add(u,v,inf,2),add(v,u,f-c,0);
            } add(n,1,inf,0); EK(); 
            return 0;
        }
    }
    signed main(){return yspm::main();}
    
    
  • 相关阅读:
    Install wget in Mac OS X Without Homebrew or MacPorts
    Embedding Lua in C: Using Lua from inside C.
    Lua 的数据结构
    Maintainable HashCode and Equals Using Apache Commons
    Multiples of 3 and 5
    Even Fibonacci numbers
    Eclipse Error: Unable to set localhost. This prevents creation of a GUID.
    Oracle中merge into的使用
    MERGE
    pl/sql tutorial
  • 原文地址:https://www.cnblogs.com/yspm/p/14353571.html
Copyright © 2011-2022 走看看