Luo Gu [P3386] bipartite graph matching

Subject to the effect:

Bipartite graph matching

text:

Many people are using the Hungarian algorithm, but in fact the network tumors can be too.

A data:

Input:

4 4 6
1 1
1 3
2 1
2 2
3 1
4 1

Output:

3

Figure look like this:

That is not on our network tumors only add a source and sink it:

The only limits are set to \ (1 \) just fine.

Code:


const int M = 3000010, N = 10010;

int n, m, s, t, tot, ee;
struct edge
{
    int y, w, op, next;
} e[M];
int head[N];

void Add(int x, int y, int w)
{
    e[++tot] = (edge){y, w, tot + 1, head[x]}; 
    head[x] = tot;
    e[++tot] = (edge){x, 0, tot - 1, head[y]}; 
    head[y] = tot; 
}
//****************************************
//**************网络流*********************
//****************************************
int dis[N];
queue <int> que;

bool bfs()
{
    while(!que.empty())que.pop();
    memset(dis, 60, sizeof(dis));
    dis[s] = 0;
    que.push(s);
    while(!que.empty())
    {
        int x = que.front();que.pop();
        for (int i = head[x]; i; i = e[i].next)
        {
            int y = e[i].y;
            if(dis[y] >= dis[x] + 1 && e[i].w)
            {
                dis[y] = dis[x] + 1;
                if(y == t) return 1;
                que.push(y);
            }
        }
    }
    return 0;
}

ll dfs(int x, ll f)
{
    if(x == t) return f;
    ll sum = 0;
    for (int i = head[x]; i; i = e[i].next)
    {
        int y = e[i].y;
        if(dis[y] == dis[x] + 1 && e[i].w)
        {
            ll f2 = dfs(y, min(e[i].w * 1ll, f - sum));
            if (!f2) dis[y] = -1;
            e[i].w -= f2; 
            e[e[i].op].w += f2;
            sum += f2;
            if (sum == f) break;
        }
    }
    return sum;
}

ll dinic()
{
    ll sum = 0;
    while(bfs()){sum += dfs(s, 1010580540);}
    return sum;
}
//****************************************
//***************main*********************
//****************************************

int main()
{
    scanf("%d%d%d", &n, &m, &ee);
    s = n + m + 1, t = n + m + 2;
    for (int i = 1; i <= ee; i++)
    {
        int x, y, w = 1;
        scanf("%d%d", &x, &y);
        y += n;
        Add(x, y, w);
    }
    for (int i = 1; i <= n; i++) Add(s, i, 1);   //连源点
    for (int i = 1; i <= m; i++) Add(i + n, t, 1);//连汇点
    printf("%lld", dinic());
    return 0;
}

Guess you like

Origin www.cnblogs.com/GJY-JURUO/p/12109923.html