【解题报告】洛谷 P1231 教辅的组成

题目链接

CSDN链接

这道题就只是一道普通的最大流问题,但是关键所在就是如何构图。要不是我看了题解,真的想不到这个构图方法呢

题目大意我就不写了,自己看好了。因为我觉得我写得可能还不如你们直接看题目的好

我疑惑的地方

我还没有做过这种有多种搭配的问题,所以我刚开始的构图思路就是:

  1. 从源点S向所有的书连一条边
  2. 从书向相关的答案和练习册连一条边
  3. 从答案和练习册向汇点T连一条边

但是,这么做显然是不对的。

正确的方法

  1. 把所有的书拆成两个点,我称之为bookstart和bookend
  2. 从源点S向每一本练习册连一条边,容量为1,表示这本练习册最多只能选一次
  3. 若练习册u和书v是对应的,从练习册u向vstart连一条容量为1的边,(事实上这里的容量只要大于等于1就可以)表示u和v是对应的。
  4. 把每一本书的bookstart向bookend连一条容量为一的边,这样就可以限制流过一本书的流量最多为1,表示每一本书最多只能被选一遍。
  5. 若书u和答案v是对应的,从书uend向v连一条容量为1的边,(事实上这里也是容量大于等于1就可以了,因为流过bookend这个点的流量最多只能是1)表示u和v是对应的
  6. 所有的答案向汇点连一条容量为1的边,表示这本答案只能被选一次
  7. 这张图的最大流即为答案所求

    图片示意大致如下

感悟

又学会了一种构图方法。但是如果不是只有三类物品,而是有四类或者更多物品的话,我就不知道怎么构图了。

AC代码

#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
const int INF=100000000;
const int N=50000;
const int M=150000;
int Head[N],Next[M],Edge[M],Ver[M],tot=1;
int D[N];
const int S=40001,T=40002;
void add(int,int,int);
int min(int,int);
int max(int,int);
bool bfs(void);
int dinic(int,int);//我用dinic算法求最大流
int main()
{
//我用Head[1~10000]存book_start
// Head[10001~20000]存练习册
// Head[20001~30000]存答案
// Head[30001~40000]存book_end
//不要问我为什么这么存,我也是随便来的
int n1,n2,n3,m1,m2;
scanf("%d%d%d",&n1,&n2,&n3);
for(int i=1;i<=n2;i++)
add(S,10000+i,1);
for(int i=1;i<=n3;i++)
add(20000+i,T,1);
for(int i=1;i<=n1;i++)
add(i,30000+i,1);
scanf("%d",&m1);
for(int i=1;i<=m1;i++)
{
int x,y;
scanf("%d%d",&x,&y);
add(10000+y,x,1);
}
scanf("%d",&m2);
for(int i=1;i<=m2;i++)
{
int x,y;
scanf("%d%d",&x,&y);
add(30000+x,20000+y,1);
}
int max_flow=0;
while(bfs()) max_flow+=dinic(S,INF);
printf("%d\n",max_flow);
return 0;
}
int dinic(int x,int flow)
{
if(x==T) return flow;
int rest=flow;
for(int p=Head[x];rest&&p;p=Next[p])
{
if(D[Ver[p]]==D[x]+1&&Edge[p])
{
int k=dinic(Ver[p],min(rest,Edge[p]));
if(!k) D[Ver[p]]=0;
Edge[p]-=k;
Edge[p^1]+=k;
rest-=k;
}
}
return flow-rest;
}
bool bfs(void)
{
memset(D,0,sizeof(D));
D[S]=1;
queue <int> q;
q.push(S);
while(!q.empty())
{
int x=q.front();
q.pop();
for(int p=Head[x];p;p=Next[p])
if(!D[Ver[p]]&&Edge[p])
{
D[Ver[p]]=D[x]+1;
if(Ver[p]==T) return 1;
q.push(Ver[p]);
}
}
return 0;
}
void add(int u,int v,int c)
{
Next[++tot]=Head[u],Head[u]=tot,Edge[tot]=c,Ver[tot]=v;
Next[++tot]=Head[v],Head[v]=tot,Edge[tot]=0,Ver[tot]=u;
}
inline int max(int a,int b)
{
return a>b?a:b;
}
inline int min(int a,int b)
{
return a<b?a:b;
}

【解题报告】洛谷 P1231 教辅的组成的更多相关文章

  1. 洛谷 P1231 教辅的组成

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

  2. 洛谷——P1231 教辅的组成

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

  3. 洛谷 P1231 教辅的组成(网络最大流+拆点加源加汇)

    题目背景 滚粗了的HansBug在收拾旧语文书,然而他发现了什么奇妙的东西. 题目描述 蒟蒻HansBug在一本语文书里面发现了一本答案,然而他却明明记得这书应该还包含一份练习题.然而出现在他眼前的书 ...

  4. [洛谷P1231] 教辅的组成

    题目大意:有n1本书,n2本练习册和n3个答案,然后又一些条件,说明某本答案可能和某本书对应,某本练习册可能和某本书对应,求最多有多少本完整的书(有书,练习册,答案) 题解:网络流,对应就连边,然后考 ...

  5. 洛谷P1231 教辅的组成 最大流

    裸题… Code: #include<cstdio> #include<cstring> #include<algorithm> #include<vecto ...

  6. 洛谷P1231 教辅的组成 网络流

    Code: #include<cstdio> #include<cstring> #include<algorithm> #include<vector> ...

  7. 洛谷 P1231教辅的组成

    题目描述 /* s->练习册(1~b)->书(b+1~a+b)->答案(a+b+1~a+b+c)->t 但是可能会有多本练习册指向同一本书,这本书又可能会指向多本答案 这样每本 ...

  8. 「洛谷P1231」教辅的组成 解题报告

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

  9. AC日记——教辅的组成 洛谷 P1231

    题目背景 滚粗了的HansBug在收拾旧语文书,然而他发现了什么奇妙的东西. 题目描述 蒟蒻HansBug在一本语文书里面发现了一本答案,然而他却明明记得这书应该还包含一份练习题.然而出现在他眼前的书 ...

随机推荐

  1. 【java项目实践】具体解释Ajax工作原理以及实现异步验证username是否存在+源代码下载(java版)

    一年前,从不知道Ajax是什么,伴随着不断的积累,到如今常常使用,逐渐有了深入的认识. 今天,假设想开发一个更加人性化,友好,无刷新,交互性更强的网页,那您的目标一定是Ajax. 介绍 在具体讨论Aj ...

  2. LeetCode 771. Jewels and Stones (宝石与石头)

    题目标签:Hash Table 这一题很简单,题目给了两个string:J 和 S. 只要把J 里面的 char 放入HashSet,再遍历S找出有多少个石头是宝石. Java Solution: R ...

  3. java错误:无法将Object转换为int类型

    Object value java要想将Object转换为int类型,就必须先将Object转换为String,然后String再转换为int,如下: Integer.parseInt(String. ...

  4. eclipse中Kotlin的基础应用

    最近逛网站时无意中发现有一门新语言谈论很广-- kotlin ,能够完全兼容Java.这就引起了楼主的好奇心,据所周知,Java就是因为多平台的支持 才流行起来.OK,闲话不多说,下面看图讲代码. 1 ...

  5. mysql大数据的分表

    在实际业务运作中,我们经常遇到一个表中数据量过大的问题,这样的话,问题就来了.如何将一个表中的数据均衡的放到多个表中? 我的建议是,新建一个表,但是只有一个自增的id字段,将其作为分表的依据.有大数据 ...

  6. cropbox

    今天给大家分享一款基于jQuery头像裁剪插件cropbox,这是一款简单实用的jQuery头像在线裁剪插件.该插件适用于适用浏览器:IE8.360.FireFox.Chrome.Safari.Ope ...

  7. codevs1557 热浪(堆优化dijkstra)

    1557 热浪  时间限制: 1 s  空间限制: 256000 KB  题目等级 : 钻石 Diamond 题解  查看运行结果     题目描述 Description 德克萨斯纯朴的民眾们这个夏 ...

  8. P3128 [USACO15DEC]最大流Max Flow(LCA+树上差分)

    P3128 [USACO15DEC]最大流Max Flow 题目描述 Farmer John has installed a new system of  pipes to transport mil ...

  9. 面试题:InnoDB中一棵B+树能存多少行数据?

    阅读本文大概需要 5 分钟. 作者:李平 | 来源:个人博客 一.InnoDB 一棵 B+ 树可以存放多少行数据? InnoDB 一棵 B+ 树可以存放多少行数据? 这个问题的简单回答是:约 2 千万 ...

  10. 微信小程序之上传多张图片

    之前写过一篇小程序商品发布的博客,里面有上传多张图片的功能,这里单独拿出来实现以下,小程序的upLoadFile一次只能上传一张图片,需要循环调这个接口来实现 for (var i = 0; i &l ...