zoukankan      html  css  js  c++  java
  • P1231 教辅的组成 最大流

      

    题目背景

    滚粗了的HansBug在收拾旧语文书,然而他发现了什么奇妙的东西。

    题目描述

    蒟蒻HansBug在一本语文书里面发现了一本答案,然而他却明明记得这书应该还包含一份练习题。然而出现在他眼前的书多得数不胜数,其中有书,有答案,有练习册。已知一个完整的书册均应该包含且仅包含一本书、一本练习册和一份答案,然而现在全都乱做了一团。许多书上面的字迹都已经模糊了,然而HansBug还是可以大致判断这是一本书还是练习册或答案,并且能够大致知道一本书和答案以及一本书和练习册的对应关系(即仅仅知道某书和某答案、某书和某练习册有可能相对应,除此以外的均不可能对应)。既然如此,HansBug想知道在这样的情况下,最多可能同时组合成多少个完整的书册。

    输入输出格式

    输入格式:

    第一行包含三个正整数N1、N2、N3,分别表示书的个数、练习册的个数和答案的个数。

    第二行包含一个正整数M1,表示书和练习册可能的对应关系个数。

    接下来M1行每行包含两个正整数x、y,表示第x本书和第y本练习册可能对应。(1<=x<=N1,1<=y<=N2)

    第M1+3行包含一个正整数M2,表述书和答案可能的对应关系个数。

    接下来M2行每行包含两个正整数x、y,表示第x本书和第y本答案可能对应。(1<=x<=N1,1<=y<=N3)

    输出格式:

    输出包含一个正整数,表示最多可能组成完整书册的数目。

    输入输出样例

    输入样例#1: 复制
    5 3 4
    5
    4 3
    2 2
    5 2
    5 1
    5 3
    5
    1 3
    3 1
    2 2
    3 3
    4 3
    
    输出样例#1: 复制
    2



    眼前有 n1 本书,n2 本练习册,n3 本答案。已知一个完整的书册均应该包含且仅包含一本书、一本练习册、一本答案。现在 HansBug 只知道 m1 个可能的书和练习册的对应关系,m2 个可能的书和答案的对应关系。HansBug 想知道在这样的情况下,最多可能同时组合成多少个完整的书册



    练习册放左边 书放中间且拆点 答案放右边就行了
    #include<bits/stdc++.h>
    using namespace std;
    //input by bxd
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define RI(n) scanf("%d",&(n))
    #define RII(n,m) scanf("%d%d",&n,&m)
    #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
    #define RS(s) scanf("%s",s);
    #define ll long long
    #define pb push_back
    #define REP(i,N)  for(int i=0;i<(N);i++)
    #define CLR(A,v)  memset(A,v,sizeof A)
    //////////////////////////////////
    #define inf 0x3f3f3f3f
    const int N=4e5+44;
    const int M=4e6+54;
    
    struct edge {
        int to, next, w;
    } e[M << 1];
    int head[N], cnt = 1;
    void add(int x, int y, int z) {
        e[++cnt] = (edge){y, head[x], z};
        head[x] = cnt;
        e[++cnt] = (edge){x, head[y], 0};
        head[y] = cnt;
    }
    int level[N];
    bool bfs(int s, int t) {
        memset(level, 0, sizeof level);
        queue<int> q;
        level[s] = 1;
        q.push(s);
        while (!q.empty()) {
            int pos = q.front();
            q.pop();
            for (int i = head[pos]; i; i = e[i].next) {
                int nx = e[i].to;
                if (!e[i].w || level[nx]) continue;
                level[nx] = level[pos] + 1;
                q.push(nx);
            }
        }
        return level[t];
    }
    int dfs(int s, int t, int flow) {
        if (s == t) return flow;
        int ret = 0;
        for (int i = head[s]; flow && i; i = e[i].next) {
            int nx = e[i].to;
            if (level[nx] == level[s] + 1 && e[i].w) {
                int tmp = dfs(nx, t, min(flow, e[i].w));
                e[i].w -= tmp;
                e[i ^ 1].w += tmp;
                flow -= tmp;
                ret += tmp;
            }
        }
        if (!ret) level[s] = 0;
        return ret;
    }
    int dinic(int s, int t) {
        int ret = 0;
        while (bfs(s, t)) ret += dfs(s, t, inf);
        return ret;
    }
    int n,m,s,t,a,b,c,q,n1,n2,n3;
    
    int main()
    {
        RIII(n1,n2,n3);//代表书 练习册 答案
        int M=n1+n2+n3;
        s=2*M,t=s+1;
    
        rep(i,1,n1)add(i,i+M,1);//书拆点
    
        rep(i,1,n2)add(s,i+n1,1);//练习连源点
    
        rep(i,1,n3)add(n1+n2+i,t,1);//答案连汇点
    
    
        RI(q);
        while(q--)
        {
            RII(a,b);
            add(b+n1,a,1);
        }
        RI(q);
        while(q--)
        {
            RII(a,b);
            add(a+M,b+n1+n2,1);
        }
        cout<<dinic(s,t);
    
    
        return 0;
    }
    View Code



  • 相关阅读:
    python 接口自动化测试--框架定型(六)
    python 接口自动化测试--框架整改(五)
    持续集成接口自动化-jmeter+ant+jenkins(一)
    记 suds 模块循环依赖的坑-RuntimeError: maximum recursion depth exceeded
    python 接口自动化测试(四)
    python 接口自动化测试(三)
    python 接口自动化测试(二)
    python 接口自动化测试(一)
    Jmeter 正则提取器
    python 正则提取(re模块)
  • 原文地址:https://www.cnblogs.com/bxd123/p/11201796.html
Copyright © 2011-2022 走看看