题目背景

滚粗了的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*]; int if_z,n1,n2,n3,s,t,ans,cnt;
int deep[maxn],m,head[maxn]; char Cget; inline void in(int &now)
{
now=,if_z=,Cget=getchar();
while(Cget>''||Cget<'')
{
if(Cget=='-') if_z=-;
Cget=getchar();
}
while(Cget>=''&&Cget<='')
{
now=now*+Cget-'';
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=,head[u]=cnt++;
edge[cnt].v=u,edge[cnt].next=head[v],edge[cnt].flow=,head[v]=cnt++;
} bool BFS()
{
memset(deep,,sizeof(deep));
deep[s]=;queue<int>que;que.push(s);
while(!que.empty())
{
int pos=que.front();
for(int i=head[pos];i>=;i=edge[i].next)
{
if(edge[i].flow!=&&deep[edge[i].v]==)
{
deep[edge[i].v]=deep[pos]+;
que.push(edge[i].v);
}
}
que.pop();
}
if(deep[t]==) return false;
else return true;
} int flowing(int now,int flow)
{
if(now==t||flow<=) return flow;
int oldflow=;
for(int i=head[now];i>=;i=edge[i].next)
{
if(deep[edge[i].v]!=deep[now]+||edge[i].flow<=) continue;
int pos=flowing(edge[i].v,min(edge[i].flow,flow));
flow-=pos;
oldflow+=pos;
edge[i].flow-=pos;
edge[i^].flow+=pos;
if(flow==) break;
}
return oldflow;
} int dinic()
{
int pos=;
while(BFS()) pos+=flowing(s,0x7ffffff);
return pos;
} int main()
{
memset(head,-,sizeof(head));
in(n2),in(n1),in(n3);
t=n1+n2+n3+,s=;int u,v;
for(int i=;i<=n1;i++) edge_add(s,i);
for(int i=;i<=n2;i++) edge_add(i+n1,t+i);
for(int i=;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\n",dinic());
return ;
}

AC日记——教辅的组成 洛谷 P1231的更多相关文章

  1. AC日记——[SDOI2015]星际战争 洛谷 P3324

    题目描述 3333年,在银河系的某星球上,X军团和Y军团正在激烈地作战. 在战斗的某一阶段,Y军团一共派遣了N个巨型机器人进攻X军团的阵地,其中第i个巨型机器人的装甲值为Ai.当一个巨型机器人的装甲值 ...

  2. AC日记——联合权值 洛谷 P1351

    题目描述 无向连通图G 有n 个点,n - 1 条边.点从1 到n 依次编号,编号为 i 的点的权值为W i ,每条边的长度均为1 .图上两点( u , v ) 的距离定义为u 点到v 点的最短距离. ...

  3. AC日记——I Hate It 洛谷 P1531

    题目背景 很多学校流行一种比较的习惯.老师们很喜欢询问,从某某到某某当中,分数最高的是多少.这让很多学生很反感. 题目描述 不管你喜不喜欢,现在需要你做的是,就是按照老师的要求,写一个程序,模拟老师的 ...

  4. AC日记——神奇的幻方 洛谷 P2615(大模拟)

    题目描述 幻方是一种很神奇的N*N矩阵:它由数字1,2,3,……,N*N构成,且每行.每列及两条对角线上的数字之和都相同. 当N为奇数时,我们可以通过以下方法构建一个幻方: 首先将1写在第一行的中间. ...

  5. AC日记——[CQOI2009]DANCE跳舞 洛谷 P3153

    [CQOI2009]DANCE跳舞 思路: 二分+最大流: 代码: #include <cstdio> #include <cstring> #include <iost ...

  6. AC日记——松江1843路 洛谷七月月赛

    松江1843路 思路: 三分: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 100005 #define ...

  7. AC日记——严酷的训练 洛谷 P2430

    严酷的训练 思路: 背包: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 5005 int n,m,bi[m ...

  8. AC日记——[SDOI2010]大陆争霸 洛谷 P3690

    [SDOI2010]大陆争霸 思路: dijkstra模板: 代码: #include <bits/stdc++.h> using namespace std; #define maxn ...

  9. AC日记——小魔女帕琪 洛谷 P3802

    小魔女帕琪 思路: 概率公式计算: 代码: #include <bits/stdc++.h> using namespace std; ],sig; int main() { ;i< ...

随机推荐

  1. 使用slot-scope复制vue中slot内容

    有时候我们的vue组件需要复制使用者传递的内容. 比如我们工程里面的轮播组件需要使用复制的slot来达到循环滚动的效果 使用者关注轮播内容的静态效果,组件负责让其滚动起来 组件: <div cl ...

  2. LeetCode(258) Add Digits

    题目 Given a non-negative integer num, repeatedly add all its digits until the result has only one dig ...

  3. ASP.NET Web网站中App_Code文件夹的作用及使用场景

    原文地址:Web Site项目和ASP.NET Web Application中App_Code文件夹的作用作者:宾的宾 我现在要建一个ASP.NET的网站了,不难吧,开始动手.如下图: 这种方法建立 ...

  4. HDU:4185-棋盘游戏

    棋盘游戏 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Problem Descri ...

  5. B - CD UVA - 624

    https://cn.vjudge.net/contest/224070#problem/B #include <iostream> #include <cstring> #i ...

  6. Linux学习-善用判断式

    利用 test 指令的测试功能 要检测系统上面某些文件或者是相关的属性时,利用 test 这个指令来工作真是好用得不 得了, 举例来说,我要检查 /dmtsai 是否存在时,使用: [dmtsai@s ...

  7. 使用像AdminLTE的前端框架,树形导航菜单实现方式都有哪些?

    之前用easyui等富前端框架开发的时候都是使用封装好的县城的插件,现在使用最新的类似AdminLTE似的前段框架实现树形菜单都用什么方式? 后台拼接html然后前端用JS append方法添加还是直 ...

  8. Java技术——Java泛型详解

    .为什么需要泛型 转载请注明出处:http://blog.csdn.net/seu_calvin/article/details/52230032 泛型在Java中有很重要的地位,网上很多文章罗列各种 ...

  9. UVa 1629 DP Cake slicing

    题意: 一块n×m的蛋糕上有若干个樱桃,要求切割若干次以后,每块蛋糕上有且仅有1个樱桃.求最小的切割长度. 分析: d(u, d, l, r)表示切割矩形(u, d, l, r)所需要的最小切割长度. ...

  10. CodeForces 570E DP Pig and Palindromes

    题意:给出一个n行m列的字符矩阵,从左上角走到右下角,每次只能往右或者往下走,求一共有多少种走法能得到回文串. 分析: 可以从两头开始考虑,每次只走一样字符的格子,这样得到的两个字符串拼起来之后就是一 ...