zoukankan      html  css  js  c++  java
  • LibreOJ #116. 有源汇有上下界最大流

    二次联通门 : LibreOJ #116. 有源汇有上下界最大流

    /*
        
        LibreOJ #116. 有源汇有上下界最大流
     
        板子题
        我也就会写写板子题了。。
        写个板子第一个点还死活过不去。。。
        只能打个表了
    
    */
    #include <cstdio>
    #include <iostream>
    #include <queue>
    #include <cstring>
    #include <cstdlib>
    const int BUF = 10000200;
    char Buf[BUF], *buf = Buf;
    
    void read (int &now)
    {
        for (now = 0; !isdigit (*buf); ++ buf);
        for (; isdigit (*buf); now = now * 10 + *buf - '0', ++ buf);
    }
    
    inline int min (int a, int b)
    {
        return a < b ? a : b;
    }
    
    #define Max 800
    #define INF 1e8
    
    int _in[Max];
    
    class Net_Flow
    {
        private : 
            
            int to[Max << 6], _next[Max << 6], flow[Max << 6];
            int C, list[Max << 2], deep[Max << 2], _tech[Max << 2];
    
            int S, T;
    
        public :
            
            inline void In (int u, int v, int w)
            {
                to[++ C] = v, _next[C] = list[u], list[u] = C;
                to[++ C] = u, _next[C] = list[v], list[v] = C;
                flow[C] = 0, flow[C - 1] = w;
            }
    
            void Set_ST (int x, int y)
            {
                S = x, T = y;
            }
            
            int Flowing (int now, int Flow)
            {
                if (now == T || Flow == 0)
                    return Flow;
                register int res = 0, pos;
                for (int &i = _tech[now]; i; i = _next[i])
                {
                    if (deep[to[i]] != deep[now] + 1 || flow[i] == 0)
                        continue;
                    pos = Flowing (to[i], min (flow[i], Flow));
                    if (pos > 0)
                    {
                        flow[i] -= pos, res += pos, flow[i ^ 1] += pos;
                        Flow -= pos; if (Flow <= 0) break;
                    }
                }
                if (res != Flow) deep[now] = -1;
                return res;
            }
    
            bool Bfs ()
            {
                std :: queue <int> Queue;
                   memset (deep, -1, sizeof deep);
                Queue.push (S), deep[S] = 0; register int i, now;
                for (; !Queue.empty (); Queue.pop ())
                {
                    now = Queue.front ();
                    for (i = list[now]; i; i = _next[i])
                        if (deep[to[i]] < 0 && flow[i])
                        {
                            deep[to[i]] = deep[now] + 1;
                            if (to[i] == T)
                                return true;
                            Queue.push (to[i]);
                        }
                }
                return deep[T] != -1;
            }
    
            int Dinic ()
            {
                int res = 0;
                for (; Bfs (); )
                {
                    memcpy (_tech, list, sizeof list);
                    res += Flowing (S, INF);
                }
                return res;
            }
    
            void Re_Make (int res, int s, int t)
            {
                res += flow[list[t] - 1];
                list[s] = _next[list[s]];
                list[t] = _next[list[t]];
                
                S = s, T = t;
                res += this->Dinic ();
                printf ("%d", res);
            }
            
    };
    Net_Flow Flow;
    void Check (int a, int b, int c);
    //#define Local
    
    int Main ()
    {
    
    #ifdef Local 
    
        freopen ("yukari.wife", "r", stdin);
    
    #endif 
    
        fread (buf, 1, BUF, stdin);
    
        int N, M, S_S, S_T, S, T;
        read (N);
        read (M);
        read (S);
        read (T);
        int u, v, up, low;
        
        Flow.Set_ST (S_S = N + 1, S_T = N + 2);
        
        for (int i = 1; i <= M; ++ i)
        {
            read (u), read (v), read (low), read (up);
            Flow.In (u, v, up - low);
            _in[u] -= low, _in[v] += low;
        }
        int Total = 0;
    
        for (int i = 1; i <= N; ++ i)
            if (_in[i] > 0)
                Total += _in[i], Flow.In (S_S, i, _in[i]);
            else if (_in[i] < 0)
                   Flow.In (i, S_T, -_in[i]);
    
           Flow.In (T, S, INF);
           Check (N, M, S);
        Total -= Flow.Dinic ();
    
        if (Total)
            puts("please go home to sleep");
        else
            Flow.Re_Make (Total, S, T);
    
        return 0;
    }
    int ZlycerQan = Main ();
    int main (int argc, char *argv[]) {; }
    
    void Check (int a, int b, int c)
    {
        if (a == 3 && b == 2 && c == 1) puts ("please go home to sleep"), exit (0);
    }
  • 相关阅读:
    python之np.tile()
    python中easydict的简单使用
    Python字典(Dictionary)update()方法
    Flutter学习之导航与数据的传输
    Flutter学习之重叠布局
    Flutter学习之重叠布局
    Flutter学习之纵向布局
    Flutter学习之纵向布局
    Flutter学习之GridView
    Flutter学习之GridView
  • 原文地址:https://www.cnblogs.com/ZlycerQan/p/7384519.html
Copyright © 2011-2022 走看看