zoukankan      html  css  js  c++  java
  • LibreOJ #6000. 「网络流 24 题」搭配飞行员

    二次联通门 : LibreOJ #6000. 「网络流 24 题」搭配飞行员

    /*
        LibreOJ #6000. 「网络流 24 题」搭配飞行员
        
        二分图最大匹配
        Dinic最大流 + 当前弧优化
         
    */
    #include <cstring>
    #include <cstdio>
    #include <queue>
    
    #define Max 10000
    #define INF 1e5
    
    int read (int &now)
    {
        now = 0;
        register char word = getchar ();
        while (word < '0' || word > '9')
            word = getchar ();
        while (word >= '0' && word <= '9')
        {
            now = now * 10 + word - '0';
            word = getchar ();
        }
        if (now >= 0)
            return 1;
    }
    
    inline int min (int a, int b)
    {
        return a < b ? a : b;
    }
    
    class Net_Flow_Type
    {
    
        private :
        
            int __to[Max << 2], __next[Max << 2];
            
            int __flow[Max << 2];
            
            int edge_list[Max];
            int Edge_Count;
            
            int deep[Max], __tech_[Max];
            int T;
            
            int Answer;
            
        public :
            
            Net_Flow_Type ()
            {
                Edge_Count = 1;
            }
            
            inline void Insert_edge (int from, int to)
            {
                Edge_Count ++;
                
                __to[Edge_Count] = to;
                __next[Edge_Count] = edge_list[from];
                edge_list[from] = Edge_Count;
                
                Edge_Count ++;
                
                __to[Edge_Count] = from;
                __next[Edge_Count] = edge_list[to];
                edge_list[to] = Edge_Count;
                
                __flow[Edge_Count - 1] = 1;
                __flow[Edge_Count] = 0;
            }
            
            bool Bfs (int Start, int End)
            {
                std :: queue <int> Queue;
                
                Queue.push (Start);
                memset (deep, -1, sizeof deep);
                
                int now;
                for (deep[Start] = 0; !Queue.empty (); Queue.pop ())
                {
                    now = Queue.front ();
                    
                    for (int i = edge_list[now]; i; i = __next[i])
                        if (__flow[i] && deep[__to[i]] == -1)
                        {
                            deep[__to[i]] = deep[now] + 1;
                            if (__to[i] == End)
                                return true;
                            Queue.push (__to[i]); 
                        }
                } 
                
                return deep[End] != -1;
            }
            
            int Flowing (int now, int flow)
            {
                if (now == T || flow <= 0)
                    return flow;
                    
                int res = 0, pos = 0;
                for (int i = __tech_[now]; i; i = __next[i])
                {
                    if (deep[__to[i]] != deep[now] + 1 || __flow[i] <= 0)
                        continue;
                    res = Flowing (__to[i], min (flow, __flow[i]));
                     
                    if (res > 0)
                    {
                        flow -= res;
                        pos += res;
                        
                        __flow[i] -= res;
                        __flow[i ^ 1] += res;
                        if (__flow[i])
                            __tech_[now] = i;
                            
                        if (flow == 0)
                            return pos;
                    }
                }
                return pos;
            }
            
            int Dinic (int Start, int End)
            {
                for (T = End; Bfs (Start, End); )
                {
                    memcpy (__tech_, edge_list, sizeof edge_list);
                    
                    Answer += Flowing (Start, INF);
                }
                
                return Answer;
            }
            
    };
    
    int N, M;
    Net_Flow_Type Make;
    
    int main (int argc, char *argv[])
    {
        read (N);
        read (M);
        
        int S = N + 1, T = N + 2;
        
        for (int i = 1; i <= M; i ++)
            Make.Insert_edge (S, i);
            
        for (int i = M + 1; i <= N; i ++)
            Make.Insert_edge (i, T);
            
        for (int x, y; scanf ("%d %d", &x, &y) == 2; Make.Insert_edge (x, y));
        
        printf ("%d", Make.Dinic (S, T));
            
        return 0;
    }
  • 相关阅读:
    java作业5
    《大道至简》第五章读后感
    java作业4
    《大道至简》第四章读后感
    java作业3
    《大道至简》第三章读后感
    java作业2
    Java课程作业1
    《大道至简》第二章读后感
    《大道至简》第一章读后感
  • 原文地址:https://www.cnblogs.com/ZlycerQan/p/7076874.html
Copyright © 2011-2022 走看看