zoukankan      html  css  js  c++  java
  • P1231 教辅的组成 拆点限流

    如果只有两个物品的话 是一个裸的二分图匹配问题

    现在变成了三个物品之间的匹配 则只要在中间加一层节点表示书 再把这层的每个点拆成两个点中间连一条边限制流量 使其只能用一次

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    using namespace std;
    #define REP(i, a, b) for(register int i = (a), i##_end_ = (b); i <= i##_end_; ++ i)
    #define DREP(i, a, b) for(register int i = (a), i##_end_ = (b); i >= i##_end_; -- i)
    #define mem(a, b) memset((a), b, sizeof(a))
    int read()
    {
        int sum = 0, fg = 1; char c = getchar();
        while(c < '0' || c > '9') { if (c == '-') fg = -1; c = getchar(); }
        while(c >= '0' && c <= '9') { sum = sum * 10 + c - '0'; c = getchar(); }
        return sum * fg;
    }
    #define inf 0x3f3f3f3f
    const int maxn = 1000000;
    int e,be[maxn], ne[maxn], to[maxn], c[maxn];
    int nb, nex, na,m1,m2;
    void add(int x, int y, int z)
    {
        to[e] = y, ne[e] = be[x], be[x] = e;
        c[e] = z, e++;
        to[e] = x, ne[e] = be[y], be[y] = e;
        c[e] = 0, e++;
    }
    int d[maxn], end;
    bool bfs()
    {    
        queue<int>q;
        memset(d,-1,sizeof(d));
        q.push(end),d[end] = 0;
        while(!q.empty())
        {
            int u = q.front(); q.pop();
            for(int i = be[u]; i!=-1; i = ne[i])
            {
                int v = to[i];
                if(d[v] == -1 && c[i ^ 1])
                {
                    d[v] = d[u] + 1;
                    q.push(v);
                }
            }
        }
        return d[0]!=-1;
    }
    int dfs(int x,int low)
    {
        if(x == end || !low)return low;
        int ret = 0;
        for(int i = be[x]; i!=-1;i = ne[i])
        {
            int v = to[i];
            if(d[v] == d[x] - 1 )
            {
                int    k = dfs(v,min(low-ret,c[i]));
                if(k > 0)
                {
                    c[i] -= k;
                    c[i^1] += k;
                    ret+=k;
                }
            }
        }
        return ret;
    }
    int dinic()
    {
        int ans = 0;
        while(bfs())
        {
            int k = dfs(0,inf);
            if(k>0)ans+=k;
        }
        return ans;
    }
    int main()
    {
        memset(be,-1,sizeof(be));    
        nb = read(); nex = read(); na = read();
        m1 = read();
        REP(i,1,m1)
        {
            int x,y;
            x = read(), y = read();
            add(y,nex+x,1);
        }
        m2 = read();
        REP(i,1,m2)
        {
            int x,y;
            x = read(), y = read();
            add(nex+nb+x,2*nb+nex+y,1);
        }
        end = 2*nb+nex+na+1;
        REP(i,1,nex)    add(0,i,1);
        REP(i,1,na) add(2*nb+nex+i,end,1);
        REP(i,1,nb) add(nex+i,nex+nb+i,1);
        printf("%d",dinic());
        return 0;
    }
    View Code
  • 相关阅读:
    AGC002
    ICPC 北美Mid Central 2019 Regional
    【洛谷 5020】货币系统
    【洛谷 1109】学生分组
    【洛谷 2915】奶牛混合起来
    【洛谷 4162】最长距离
    【YCOJ 3805】竞选
    【洛谷 2807】最长路
    【洛谷 2918】买干草Buying Hay
    【LOJ 10172】涂抹果酱
  • 原文地址:https://www.cnblogs.com/Aragaki/p/10648166.html
Copyright © 2011-2022 走看看