luogu P1231 The composition of teaching assistants (maps, points, maximum flow)

luogu P1231 Teaching assistant composition

Insert picture description here

Insert picture description here

Every book must be divided into points, divided into entry and exit points, because each book can only be matched once

Image Source

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>

using namespace std;
typedef long long ll;
int n, m, S, T;

namespace dinic{
    
    
    const int N = 500007, M = 5000007, INF = 0x3f3f3f3f;
    const ll LINF = 0x3f3f3f3f3f;

    int n, m, S, T;
    int deep[M];
    ll maxflow, edge[M];
    int head[N], ver[M], nex[M], tot, cur[N];

    inline void add(int x, int y, int z, bool o = 1)
    {
    
    
        ver[tot] = y;
        edge[tot] = z;
        nex[tot] = head[x];
        head[x] = tot ++ ;
        if(o)add(y, x, 0, 0);
    }

    bool bfs(){
    
    
        queue<int>q;
        memset(deep, 0x3f, sizeof deep);
        deep[S] = 0;
        cur[S] = head[S];
        q.push(S);
        while(q.size()){
    
    
            int x = q.front();
            q.pop();

            for(int i = head[x]; ~i; i = nex[i]){
    
    
                int y = ver[i], z = edge[i];
                if(z > 0 && deep[y] == INF){
    
    
                    q.push(y);
                    deep[y] = deep[x] + 1;
                    cur[i] = head[i];
                    if(y == T)return true;
                }
            }
        }
        return false;
    }

    ll dfs(int x, ll flow)
    {
    
    
        if(x == T)return flow;
        ll ans = 0, i, k;
        for(i = cur[x] ;~i &&flow; i = nex[i]){
    
    
            int y = ver[i];
            ll z = edge[i];
            if(z > 0 && deep[y] == deep[x] + 1){
    
    
                k = dfs(y, min(flow, z));
                if(k == 0)deep[y] = INF;
                edge[i] -= k;
                edge[i ^ 1] += k;
                ans += k;
                flow -= k;
            }
        }
        return ans;
    }

    inline void main()
    {
    
    
        while(bfs()){
    
    
            memcpy(cur, head, sizeof head);
            maxflow += dfs(S, LINF);
        }
    }

    inline void init(int _n, int _S, int _T)
    {
    
    
        n = _n, S = _S, T = _T;
        memset(head, -1, sizeof head);
        tot = 0, maxflow = 0;

    }
}


int n1, n2, n3, m1, m2;
int main()
{
    
    
    //1 ~ n1                             : 书,入点
    //n1 ~ 2 * n1                        : 书,出点
    //2 * n1 + 1 ~ 2 * n1 + n2           : 练习册,练习册连书的入点
    //2 * n1 + n2 + 1 ~ 2 * n1 + n2 + n3 : 答案,书的出点连答案
    scanf("%d%d%d", &n1, &n2, &n3);
    S = 0, T = n1 + n2 + n3 + n1 + 1;

    dinic::init(T * 10, S, T);

    for(int i = 1; i <= n1; ++ i){
    
    
        dinic::add(i, i + n1, 1);
    }
    scanf("%d", &m1);

    for(int i = 1; i <= m1;++ i){
    
    
        int x, y;
        scanf("%d%d", &x, &y);
        dinic::add(y + 2 * n1, x, 1);
    }
    scanf("%d", &m2);

    for(int i = 1; i <= m2; ++ i){
    
    
        int x, y;
        scanf("%d%d", &x, &y);
        dinic::add(x + n1, y + 2 * n1 + n2, 1);
    }

    for(int i = 1; i <= n2; ++ i){
    
    
        dinic::add(S, 2 * n1 + i, 1);
    }

    for(int i = 1; i <= n3; ++ i){
    
    
        dinic::add(2 * n1 + n2 + i, T, 1);
    }
    dinic::main();
    printf("%lld\n", dinic::maxflow);
    return 0;
}


Guess you like

Origin blog.csdn.net/weixin_45697774/article/details/108672019