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;
}

 

posted @ 2017-06-25 15:19  ZlycerQan  阅读(179)  评论(0编辑  收藏  举报