P1231 教辅的组成
传送门:https://www.luogu.org/problemnew/show/P1231
这是一道很不错的网络流入门题,关键在于如何建图。
首先,我们将练习册和源点连一条边权为1的边,然后若书 i 和练习册 j 可以配套,就将连一条从练习册 j 到书 i 边,当然边权还是1。同理,答案和书也是如此,最后再将答案和汇点连一条边权为1的边。
但是这么写还是会有点问题,因为经过一本书的路径可能与很多条,书就被使用了多次,显然不符合题意。这时候我们可以将书 i 拆成书 i1 和 i2,i1 和练习册连边,i2 和答案连边,这样就保证没一本书之用过一次了。
建好图后跑最大流就行了。
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<stack>
#include<queue>
#include<vector>
using namespace std;
#define enter printf("\n")
#define space printf(" ")
#define Mem(a) memset(a, 0, sizeof(a))
typedef long long ll;
typedef double db;
const int INF = 0x3f3f3f3f;
const db eps = 1e-;
const int maxn = 1e4 + ;
inline ll read()
{
ll ans = ;
char ch = getchar(), last = ' ';
while(!isdigit(ch)) {last = ch; ch = getchar();}
while(isdigit(ch))
{
ans = ans * + ch - ''; ch = getchar();
}
if(last == '-') ans = -ans;
return ans;
}
inline void write(ll x)
{
if(x < ) x = -x, putchar('-');
if(x >= ) write(x / );
putchar(x % + '');
} int t, n1, n2, n3; struct Edge
{
int from, to, cap, flow;
};
vector<Edge> edges;
vector<int> G[maxn << ];
void addEdge(int from, int to)
{
edges.push_back((Edge){from, to, , });
edges.push_back((Edge){to, from, , });
int sz = edges.size();
G[from].push_back(sz - );
G[to].push_back(sz - );
} int dis[maxn << ];
bool vis[maxn << ];
bool bfs()
{
Mem(vis);
queue<int> q;
q.push(); vis[] = ;
dis[] = ;
while(!q.empty())
{
int now = q.front(); q.pop();
for(int i = ; i < (int)G[now].size(); ++i)
{
Edge& e = edges[G[now][i]];
if(!vis[e.to] && e.cap > e.flow)
{
vis[e.to] = ;
dis[e.to] = dis[now] + ;
q.push(e.to);
}
}
}
return vis[t];
}
int cur[maxn << ];
int dfs(int now, int a)
{
if(now == t || !a) return a;
int flow = , f;
for(int& i = cur[now]; i < (int)G[now].size(); ++i)
{
Edge& e = edges[G[now][i]];
if(dis[e.to] == dis[now] + && (f = dfs(e.to, min(a, e.cap - e.flow))) > )
{
e.flow += f;
edges[G[now][i] ^ ].flow -= f;
flow += f; a -= f;
if(!a) break;
}
}
return flow;
} int maxflow()
{
int flow = ;
while(bfs())
{
Mem(cur);
flow += dfs(, INF);
}
return flow;
} //bool vis2[maxn]; int main()
{
n1 = read(); n2 = read(); n3 = read();
t = (n1 << )+ n2 + n3 + ; //为了防止编号重复
/*按注释掉的写法会WA掉,因为如果一本书多次输入,那么这个书
就多次拆点,这一本书就可以使用多次了 */
/* int m = read();
while(m--)
{
int x = read(), y = read();
addEdge(0, y + (n1 << 1));
addEdge(y + (n1 << 1), x);
addEdge(x, x + n1);
vis2[x] = 1;
}
m = read();
while(m--)
{
int x = read(), y = read();
if(!vis2[x]) addEdge(x, x + n1), vis2[x] = 1;
addEdge(x + n1, y + (n1 << 1) + n2);
addEdge(y + (n1 << 1) + n2, t);
}*/
int m = read();
while(m--)
{
int x = read(), y = read();
addEdge(y + (n1 << ), x);
}
m = read();
while(m--)
{
int x = read(), y = read();
addEdge(x + n1, y + (n1 << ) + n2);
}
for(int i = ; i <= n1; ++i) addEdge(i, i + n1);
for(int i = ; i <= n2; ++i) addEdge(, i + (n1 << ));
for(int i = ; i <= n3; ++i) addEdge(i + (n1 << ) + n2, t);
write(maxflow()); enter;
}
P1231 教辅的组成的更多相关文章
- Luogu P1231 教辅的组成
Luogu P1231 教辅的组成 题目背景 滚粗了的HansBug在收拾旧语文书,然而他发现了什么奇妙的东西. 题目描述 蒟蒻HansBug在一本语文书里面发现了一本答案,然而他却明明记得这书应该还 ...
- 洛谷 P1231 教辅的组成
P1231 教辅的组成 题目背景 滚粗了的HansBug在收拾旧语文书,然而他发现了什么奇妙的东西. 题目描述 蒟蒻HansBug在一本语文书里面发现了一本答案,然而他却明明记得这书应该还包含一份练习 ...
- 洛谷——P1231 教辅的组成
P1231 教辅的组成 题目背景 滚粗了的HansBug在收拾旧语文书,然而他发现了什么奇妙的东西. 题目描述 蒟蒻HansBug在一本语文书里面发现了一本答案,然而他却明明记得这书应该还包含一份练习 ...
- 【解题报告】洛谷 P1231 教辅的组成
[解题报告]洛谷 P1231 教辅的组成 题目链接 CSDN链接 这道题就只是一道普通的最大流问题,但是关键所在就是如何构图.要不是我看了题解,真的想不到这个构图方法呢 题目大意我就不写了,自己看好了 ...
- P1231 教辅的组成(最大流)
P1231 教辅的组成 这个题一看便知是网络流量,(三分图??滑稽..) 就一个小细节,如果我们仅仅将所有的点分成三部分跑网络流的话会有点小问题.. 因为这可能导致一本书被重复利用,就是有两条流经过同 ...
- 【luogu P1231 教辅的组成】 题解
题目链接:https://www.luogu.org/problemnew/show/P1231 对于每本书只能用一次,所以拆点再建边 #include <queue> #include ...
- 洛谷 P1231 教辅的组成(网络最大流+拆点加源加汇)
题目背景 滚粗了的HansBug在收拾旧语文书,然而他发现了什么奇妙的东西. 题目描述 蒟蒻HansBug在一本语文书里面发现了一本答案,然而他却明明记得这书应该还包含一份练习题.然而出现在他眼前的书 ...
- [洛谷P1231] 教辅的组成
题目大意:有n1本书,n2本练习册和n3个答案,然后又一些条件,说明某本答案可能和某本书对应,某本练习册可能和某本书对应,求最多有多少本完整的书(有书,练习册,答案) 题解:网络流,对应就连边,然后考 ...
- 【Luogu】P1231教辅的组成(拆点+Dinic+当前弧优化)
题目链接 妈耶 我的图建反了两次 准确的说是有两个地方建反了,然后反上加反改了一个小时…… 知道为什么要拆点吗? 假设这是你的图 左边到右边依次是超级源点 练习册 书 答案 ...
随机推荐
- swift 基础小结01 --delegate、Optional、GCD的使用、request请求、网络加载图片并保存到沙箱、闭包以及桥接
本文主要记录swift中delegate的使用.“?!”Optional的概念.GCD的使用.request请求.网络加载图片并保存到沙箱.闭包以及桥接. 一.delegate的使用 swift中de ...
- Number Sequence(hdu4390)
Number Sequence Time Limit: 10000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Tot ...
- Gson 使用和原理
使用教程: http://blog.csdn.net/axuanqq/article/details/51441590 http://www.jianshu.com/p/fc5c9cdf3aab 源码 ...
- Oracle中UNION和ORDER BY共用方法
问题 SQL语句中,UNION拼接两个单独的SQL时候,单独的SQL中加入ORDER BY会报错,ORDER BY只能放在句末. // 会报错的语句 SELECT S.S_ID AS ID,S.S_N ...
- Linux常用基本命令(软链接与硬链接 )
硬链接:相当于文件的多个入口,作用:备份文件,创建快照等 软链接:相当于windows的快捷方式 命令格式: ln option 源文件 目标文件 -s: 创建软链接 1,创建硬链接: ghostwu ...
- intellij idea 2016.3.5 控制台取消行数限制
有时候我们要输出大量的信息放到控制台显示,但是多了之后就出现最上面的信息被覆盖删除, 因此就需要设置控制台的显示行数,但在idea7之后的版本中,取消了对控制台行数设置选项, 只能通过更改配置文件进行 ...
- JS 数组对象根据下标拆分成新的数组
真为难啊! var arr = [ {guigeArr:['蓝色','XL','3','S']}, {guigeArr:['蓝色','L','6','S']}, {guigeArr:['蓝色','L' ...
- Salesforce中如何删除调试日志
大家在新建一个用户跟踪标记的时候可能会遇到以下报错:调试日志已经超过了上限,在编辑跟踪标志前,删除一些调试日志.但是在点击“全部删除”按钮删除所有可见的日志后,还是报同样的错误,这时候,我们打开开发者 ...
- 安卓开发环境配置之Windows+ADT+eclipse
安卓环境搭建之Windows+ADT+eclipse 要点: 1.安装JDK 2.安装Android SDK 3.安装eclipse 4.安装ADT 5.安装调试环境 正文: 1.安装JDK 1.1准 ...
- Android 外部启动activity,自定义action,action常量大全
从任意app,启动另外一个app的activity: 1. Intent i = new Intent(); ComponentName cn = new ComponentN ...