题目链接

  妈耶

  我的图建反了两次    准确的说是有两个地方建反了,然后反上加反改了一个小时……

  知道为什么要拆点吗?

  

  假设这是你的图   左边到右边依次是超级源点    练习册     书     答案     超级汇点

  请问这张图的最大流是多少?

  如果把中间拆成这样:

  

  Book-in是跟练习册匹配的书的入端,Book-out是跟答案匹配的书的出端。相当于每本书都是一条隧道,有入口有出口,每本书的入口和对应的出口连边。

  请问现在这张图的最大流是多少?

  所以你看。

  代码放上:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cctype> inline long long read(){
long long num=,f=;
char ch=getchar();
while(!isdigit(ch)){
if(ch=='-') f=-;
ch=getchar();
}
while(isdigit(ch)){
num=num*+ch-'';
ch=getchar();
}
return num*f;
} struct Edge{
int next,to,val;
}edge[];
int head[],num=-;
inline void add(int from,int to,int val){
edge[++num]=(Edge){ head[from],to,val};
head[from]=num;
} bool vis[];
int dfn[];
int list[];
int f[],h,t=;
int n,m,Start,End; bool bfs(){
memset(vis,,sizeof(vis));
f[]=Start;vis[Start]=;dfn[Start]=;h=;t=;
while(h++<t){
int from=f[h];
for(int i=head[from];i!=-;i=edge[i].next){
int to=edge[i].to;
if(vis[to]||(!edge[i].val)) continue;
dfn[to]=dfn[from]+;
vis[to]=;
f[++t]=to;
}
}
return vis[End];
} int dfs(int x,int val){
if(x==End||val==) return val;
int flow=;
vis[x]=;
for(int &i=list[x];i!=-;i=edge[i].next){
int to=edge[i].to;
if(dfn[to]==dfn[x]+&&!vis[to]&&edge[i].val>){
int now=dfs(to,std::min(edge[i].val,val));
if(now>){
edge[i].val-=now;
edge[i^].val+=now;
flow+=now;val-=now;
if(val<=) break;
}
}
}
if(flow!=val) dfn[x]=-;
return flow;
} int ans; int main(){
memset(head,-,sizeof(head));
int n1=read(),n2=read(),n3=read();
int n=n1*+n2;int N=n+n3;End=N+;
int m1=read();
for(int i=;i<=m1;++i){
int book=read(),note=read();
add(note+n1*,book,);
add(book,note+n1*,);
}
int m2=read();
for(int i=;i<=m2;++i){
int book=read(),ansnote=read();
add(book+n1,ansnote+n,);
add(ansnote+n,book+n1,);
}
for(int i=;i<=n1;++i){
add(i,i+n1,);
add(i+n1,i,);
}
for(int i=;i<=n2;++i){
add(Start,i+n1*,);
add(i+n1*,Start,);
}
for(int i=;i<=n3;++i){
add(i+n,End,);
add(End,i+n,);
}
while(bfs()){
memset(vis,,sizeof(vis));
for(int i=;i<=End;++i) list[i]=head[i];
int now=dfs(Start,0x7fffffff);
if(!now) break;
ans+=now;
}
printf("%d",ans);
return ;
}

  话说当前弧优化真好用

【Luogu】P1231教辅的组成(拆点+Dinic+当前弧优化)的更多相关文章

  1. Luogu P1231 教辅的组成

    Luogu P1231 教辅的组成 题目背景 滚粗了的HansBug在收拾旧语文书,然而他发现了什么奇妙的东西. 题目描述 蒟蒻HansBug在一本语文书里面发现了一本答案,然而他却明明记得这书应该还 ...

  2. ARC085E(最小割规划【最大流】,Dinic当前弧优化)

    #include<bits/stdc++.h>using namespace std;typedef long long ll;const ll inf=0x3f3f3f3f;int cn ...

  3. Dinic当前弧优化 模板及教程

    在阅读本文前,建议先自学最大流的Ek算法. 引入 Ek的核心是执行bfs,一旦找到增广路就停下来进行增广.换言之,执行一遍BFS执行一遍DFS,这使得效率大大降低.于是我们可以考虑优化. 核心思路 在 ...

  4. [Poj2112][USACO2003 US OPEN] Optimal Milking [网络流,最大流][Dinic+当前弧优化]

    题意:有K个挤奶机编号1~K,有C只奶牛编号(K+1)~(C+K),每个挤奶机之多能挤M头牛,现在让奶牛走到挤奶机处,求奶牛所走的最长的一条边至少是多少. 题解:从起点向挤奶机连边,容量为M,从挤奶机 ...

  5. P3376 网络流-最大流模板题(Dinic+当前弧优化)

    (点击此处查看原题) Dinic算法 Dinic算法相对于EK算法,主要区别在于Dinic算法对图实现了分层,使得我们可以用一次bfs,一次dfs使得多条增广路得到增广 普通的Dinic算法已经可以处 ...

  6. HDU 4280 Island Transport(dinic+当前弧优化)

    Island Transport Description In the vast waters far far away, there are many islands. People are liv ...

  7. 【luogu P1231 教辅的组成】 题解

    题目链接:https://www.luogu.org/problemnew/show/P1231 对于每本书只能用一次,所以拆点再建边 #include <queue> #include ...

  8. P1231 教辅的组成 拆点限流

    如果只有两个物品的话 是一个裸的二分图匹配问题 现在变成了三个物品之间的匹配 则只要在中间加一层节点表示书 再把这层的每个点拆成两个点中间连一条边限制流量 使其只能用一次 #include<io ...

  9. 网络流小记(EK&dinic&当前弧优化&费用流)

    欢 迎 来 到 网 络 瘤 的 世 界 什么是网络流? 现在我们有一座水库,周围有n个村庄,每个村庄都需要水,所以会修水管(每个水管都有一定的容量,流过的水量不能超过容量).最终水一定会流向唯一一个废 ...

随机推荐

  1. block 应用说明

    一.Block定义 Block可以理解为一个函数指针(即它是一个指针,指向某个函数) returnType (^blockName) (parameter list) = ^ (parameter l ...

  2. Azure Linux 云主机使用Root超级用户登录

    Azure的Linux虚拟机是可以灵活使用root超级用户的管理员权限的: 1:使用sudo passwd root指令设置超级用户root密码: 使用创建Linux时设置的用户名和密码登陆,使用su ...

  3. iOS 多尺寸屏幕适配

    Point Point可以理解为iOS程序员眼中的大小单位.它是iOS操作系统中的抽象的概念. Rendered Pixels可以理解为UI设计师眼中的大小单位. Physical Pixels 设备 ...

  4. jni ndk 入门

    1. Linux环境模拟,下载sygwin 安装,选择devl 和shell -> install sygwin 中的配置ndk环境,进入安装目录c:/cygwin64 etc/profile文 ...

  5. 快学UiAutomator UiDevice API 详解

    一.按键使用 返回值 方法名 说明 boolean pressBack() 模拟短按返回back键 boolean pressDPadCenter() 模拟按轨迹球中点按键 boolean press ...

  6. VS打包软件部署------ClickOnce应用安装 (各版本.net引导文件安装,再发布文档离线安装下载地址)

    一.1.其他引导程序包:地址  https://msdn.microsoft.com/zh-cn/vstudio/bb898654.aspx 2.离线安装各版本.net下载版(各种语言):https: ...

  7. Java多线程编程核心(1)

    Java多线程编程核心(1) 停止线程 本节主要讨论如何更好停止一个线程.停止线程意味着在线程处理完成任务之前放弃当前操作. 1.停不了的线程 可能大多数同学会使用interrupt()来停止线程,但 ...

  8. shelll脚本,根据软链接,找到真实路径

    [root@localhost tmp]# ls -l total lrwxrwxrwx root root Sep : abc -> /etc/passwd lrwxrwxrwx root r ...

  9. Leetcode 7 反转整数Reverse Integer

    给定一个 32 位有符号整数,将整数中的数字进行反转. 示例 1: 输入: 123 输出: 321  示例 2: 输入: -123 输出: -321 示例 3: 输入: 120 输出: 21 注意: ...

  10. LeetCode 最长连续递增序列

    给定一个未经排序的整数数组,找到最长且连续的的递增序列. 示例 1: 输入: [1,3,5,4,7] 输出: 3 解释: 最长连续递增序列是 [1,3,5], 长度为3. 尽管 [1,3,5,7] 也 ...