• AC日记——教辅的组成 洛谷 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=5,N2=3,N3=4,表示书有5本、练习册有3本、答案有4本。

    M1=5,表示书和练习册共有5个可能的对应关系,分别为:书4和练习册3、书2和练习册2、书5和练习册2、书5和练习册1以及书5和练习册3。

    M2=5,表示数和答案共有5个可能的对应关系,分别为:书1和答案3、书3和答案1、书2和答案2、书3和答案3以及书4和答案3。

    所以,以上情况的话最多可以同时配成两个书册,分别为:书2+练习册2+答案2、书4+练习册3+答案3。

    数据规模:

    对于数据点1, 2, 3,M1,M2<= 20

    对于数据点4~10,M1,M2 <= 20000

    思路:

      网络流(一眼看出= =);

      dinic算法跑最大流;

      s连接练习册,练习册连接书,书连接答案,答案连接t;

      边的容量都为1;

      然后,说几个浪费我大量时间找错的大坑:

      1 数组开到足够大

      2 拆点!

      3 head初始为-1,然后从0开始加边,便于^

    来,上代码:

    #include <queue>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    #define maxn 500005
    
    using namespace std;
    
    struct EdgeType {
        int v,next,flow;
    };
    struct EdgeType edge[maxn*10];
    
    int if_z,n1,n2,n3,s,t,ans,cnt;
    int deep[maxn],m,head[maxn];
    
    char Cget;
    
    inline void in(int &now)
    {
        now=0,if_z=1,Cget=getchar();
        while(Cget>'9'||Cget<'0')
        {
            if(Cget=='-') if_z=-1;
            Cget=getchar();
        }
        while(Cget>='0'&&Cget<='9')
        {
            now=now*10+Cget-'0';
            Cget=getchar();
        }
        now*=if_z;
    }
    
    inline void edge_add(int u,int v)
    {
        edge[cnt].v=v,edge[cnt].next=head[u],edge[cnt].flow=1,head[u]=cnt++;
        edge[cnt].v=u,edge[cnt].next=head[v],edge[cnt].flow=0,head[v]=cnt++;
    }
    
    bool BFS()
    {
        memset(deep,0,sizeof(deep));
        deep[s]=1;queue<int>que;que.push(s);
        while(!que.empty())
        {
            int pos=que.front();
            for(int i=head[pos];i>=0;i=edge[i].next)
            {
                if(edge[i].flow!=0&&deep[edge[i].v]==0)
                {
                    deep[edge[i].v]=deep[pos]+1;
                    que.push(edge[i].v);
                }
            }
            que.pop();
        }
        if(deep[t]==0) return false;
        else return true;
    }
    
    int flowing(int now,int flow)
    {
        if(now==t||flow<=0) return flow;
        int oldflow=0;
        for(int i=head[now];i>=0;i=edge[i].next)
        {
            if(deep[edge[i].v]!=deep[now]+1||edge[i].flow<=0) continue;
            int pos=flowing(edge[i].v,min(edge[i].flow,flow));
            flow-=pos;
            oldflow+=pos;
            edge[i].flow-=pos;
            edge[i^1].flow+=pos;
            if(flow==0) break;
        }
        return oldflow;
    }
    
    int dinic()
    {
        int pos=0;
        while(BFS()) pos+=flowing(s,0x7ffffff);
        return pos;
    }
    
    int main()
    {
        memset(head,-1,sizeof(head));
        in(n2),in(n1),in(n3);
        t=n1+n2+n3+1,s=0;int u,v;
        for(int i=1;i<=n1;i++) edge_add(s,i);
        for(int i=1;i<=n2;i++) edge_add(i+n1,t+i);
        for(int i=1;i<=n3;i++) edge_add(i+n1+n2,t);
        in(m);
        while(m--)
        {
            in(v),in(u);
            edge_add(u,v+n1);
        }
        in(m);
        while(m--)
        {
            in(u),in(v);
            edge_add(u+t,n1+n2+v);
        }
        printf("%d
    ",dinic());
        return 0;
    }
  • 相关阅读:
    NOIP2014D2T2寻找道路(Spfa)
    【割点】【割边】tarjan
    NOIP2013D1T3货车运输(最大生成树+倍增lca)
    lca最近公共祖先(模板)
    人生第一次hash
    【模板】Tarjan求强连通分量
    【模板】链式前向星+spfa
    二叉树的三种遍历
    hdu 3549 最大流
    hdu 1532&&poj1273 基础最大流
  • 原文地址:https://www.cnblogs.com/IUUUUUUUskyyy/p/6430835.html
Copyright © 2020-2023  润新知