zoukankan      html  css  js  c++  java
  • 教辅的组成

    题目背景

    滚粗了的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

    思路:网络流构图+最大流+拆点

    一开始,我是把s与书相连,书与教辅相连,然后教辅与答案相连,然后W0了。

    因为,教辅也只有一份的,所以还要教辅与教辅相连。

    然后又W10了,因为,书才是承上启下的。

    代码实现:

     1 #include<cstdio>
     2 #include<cstring>
     3 const int inf=1e8;
     4 const int maxn=80000;
     5 const int maxm=800000;
     6 int n1,n2,n3,m1,m2,s,t,ans;
     7 int a,b,c;
     8 inline int min_(int x,int y){return x<y?x:y;}
     9 int h[maxn],hs=1;
    10 struct edge{int s,n,w;}e[maxm];
    11 void add(int q,int z){
    12     e[++hs]=(edge){z,h[q],1},h[q]=hs;
    13     e[++hs]=(edge){q,h[z]},h[z]=hs;
    14 }
    15 int d[maxn],q[maxn],head,tail;
    16 void bfs(){
    17     memset(d,0,sizeof(d));
    18     head=tail=0;
    19     q[head++]=s,d[s]=1;
    20     while(head>tail){
    21         a=q[tail++];
    22         for(int i=h[a];i;i=e[i].n)
    23         if(!d[e[i].s]&&e[i].w){
    24             d[e[i].s]=d[a]+1;
    25             if(e[i].s==t) return;
    26             q[head++]=e[i].s;
    27         }
    28     }
    29 }
    30 int ap(int k,int w){
    31     if(k==t)
    32     return w;
    33     int uw=w;
    34     for(int i=h[k];i&&uw;i=e[i].n)
    35     if(d[e[i].s]==d[k]+1&&e[i].w){
    36         int nw=ap(e[i].s,min_(uw,e[i].w));
    37         if(nw) e[i].w-=nw,e[i^1].w+=nw,uw-=nw;
    38         else d[e[i].s]=0;
    39     }
    40     return w-uw;
    41 }
    42 void Dinic(){while(bfs(),d[t]) ans+=ap(s,inf);}
    43 int main(){
    44     scanf("%d%d%d",&n2,&n1,&n3);
    45     s=0,t=n1+n1+n2+n3+1;
    46     for(int i=1;i<=n1;i++) add(s,i);
    47     for(int i=1;i<=n2;i++) add(i+n1,i+n1+n2);
    48     for(int i=1;i<=n3;i++) add(i+n1+n2+n2,t);
    49     scanf("%d",&m1);
    50     for(int i=1;i<=m1;i++) scanf("%d%d",&b,&a),add(a,b+n1);
    51     scanf("%d",&m2);
    52     for(int i=1;i<=m2;i++) scanf("%d%d",&a,&b),add(a+n1+n2,b+n1+n2+n2);
    53     Dinic();
    54     printf("%d
    ",ans);
    55     return 0;
    56 }

    题目来源:洛谷

  • 相关阅读:
    Docker部署nginx
    解决网页在手机端适配问题
    记一次Jenkins+Docker+gitlab自动化部署vue
    Docker部署jenkins
    备案
    Jenkins插件使用--Publish Over SSH
    打开root用户ssh登陆
    gitlab配置git
    Dokcer容器内无法域名解析
    vue开发环境搭建
  • 原文地址:https://www.cnblogs.com/J-william/p/6599579.html
Copyright © 2011-2022 走看看