luogu P1231 La composición de los profesores asistentes (mapas, puntos, flujo máximo)

luogu P1231 Composición de asistente de enseñanza

Inserte la descripción de la imagen aquí

Inserte la descripción de la imagen aquí

Cada libro debe dividirse en puntos, divididos en puntos de entrada y salida, porque cada libro solo se puede emparejar una vez.

Fuente de imagen

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


Supongo que te gusta

Origin blog.csdn.net/weixin_45697774/article/details/108672019
Recomendado
Clasificación