luogu P3386 【模板】二分图匹配

二次联通门 : luogu P3386 【模板】二分图匹配

 

 

 

 

 

/*
    luogu P3386 【模板】二分图匹配
    
    最大流
    设置源点,汇点,连到每条边上
    跑一边最大流即可 
*/
#include <iostream>
#include <cstring> 
#include <cstdio>
#include <queue>

#define Max 100008
#define INF 1e7

using namespace std;

inline int min (int a, int b)
{
    return a < b ? a : b;
}

void read (int &now)
{
    now = 0;
    char word = getchar ();
    while (word > '9' || word < '0')
        word = getchar ();
    while (word >= '0' && word <= '9')
    {
        now = now * 10 + word - '0';
        word = getchar ();
    }
}

struct Edge
{
    int from;
    int to;
    int flow;
    int next; 
}edge[Max << 6];

int deep[Max];
int Edge_Count;
int edge_list[Max];
int S, T;

inline void AddEdge (int from, int to, int dis)
{
    Edge_Count++;
    edge[Edge_Count].to = to;
    edge[Edge_Count].flow = dis;
    edge[Edge_Count].next = edge_list[from];
    edge_list[from] = Edge_Count;
}

int Get_Flow (int now, int flow)
{
    if (now == T || flow <= 0)
        return flow;
    int res = 0, pos;
    for (int i = edge_list[now]; i; i = edge[i].next)
    {
        if (deep[edge[i].to] != deep[now] + 1 || edge[i].flow <= 0)
            continue;
        pos = Get_Flow (edge[i].to, min (edge[i].flow, flow));        
        edge[i].flow -= pos;
        edge[i ^ 1].flow += pos;
        res += pos;
        flow -= pos;
        if (flow <= 0)
            return res;
    }
    return res;
}

int E, N, M;
int Answer;

void Bfs ()
{
    while (true)
    {
        bool flag = false;
        memset (deep, -1, sizeof deep);
        queue <int> Queue;
        Queue.push (S);
        deep[S] = 0;
        int now;
        while (!Queue.empty ()) 
        {
            now = Queue.front ();
            Queue.pop ();
            for (int i = edge_list[now]; i; i = edge[i].next)
                if (deep[edge[i].to] < 0 && edge[i].flow)
                {
                    deep[edge[i].to] = deep[now] + 1;
                    if (edge[i].to == T)
                    {
                        flag = true;
                        break;
                    }
                    Queue.push (edge[i].to); 
                }
            if (flag)
                break;
        }
        if (deep[T] <= 0)
            break;
        Answer += Get_Flow (S, INF);
    }
}

int main (int argc, char *argv[])
{
    read (N);
    read (M);
    read (E);
    S = Max - 1;
    T = Max - 2;
    int x, y;
    for (int i = 1; i <= E; i++)
    {
        read (x);
        read (y);
        if (x > M || y > M)
            continue;
        AddEdge (x, N + y + 10, 1);
        AddEdge (N + y + 10, x, 0);
    }
    for (int i = 1; i <= N; i++)
    {
        AddEdge (S, i, 1);
        AddEdge (i, S, 0);
    }
    for (int i = 1; i <= M; i++)
    {
        AddEdge (N + i + 10, T, 1);
        AddEdge (T, N + i + 10, 0);
    }
    Bfs ();
    printf ("%d", Answer);
    return 0;
}

 

posted @ 2017-05-20 17:37  ZlycerQan  阅读(198)  评论(0编辑  收藏  举报