【解题报告】洛谷 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. Android Path路径设置,针对error opening trace file:No such file or directory

    对于android的开发者来说,首先要做的就是环境变量的配置.学习过java的人都知道,java是须要配置环境变量的,那么android开发是否也须要我们配置环境变量呢?当然,安卓的环境变量须要我们配 ...

  2. MySQL中採用类型varchar(20)和varchar(255)对性能上的影响

    1.MySQL建立索引时假设没有限制索引的大小,索引长度会默认採用的该字段的长度.也就是说varchar(20)和varchar(255)相应的索引长度分别为20*3(utf-8)(+2+1),255 ...

  3. LeetCode 69. Sqrt(x) (平方根)

    Implement int sqrt(int x). Compute and return the square root of x. x is guaranteed to be a non-nega ...

  4. 深入理解7816(2)---关于ATR【转】

    本文转载自:http://blog.sina.com.cn/s/blog_4df8400a0102vcrk.html 深入理解7816(2)---关于ATR 智能卡(此处主要指接触式CPU卡)本身始终 ...

  5. Bing Maps进阶系列四:路由功能服务(RouteService)

    Bing Maps进阶系列四:路由功能服务(RouteService) Bing Maps提供的路由功能服务(RouteService)可以实现多方位的计算地图上的路线指示,路径行程等功能,比如说实现 ...

  6. android 中activity 属性说明(转载)

    转自:http://liuwuhen.iteye.com/blog/1759796 activity是android中使用非常平凡的一种组件,我们除了需要掌握activity中的生命周期以外,还需要掌 ...

  7. HTTP Status 500 - Could not write content: could not initialize proxy - no Session

    分析出现no Session错误的原因以及给出解决方案: 使用SpringMVC + JSON数据返回时,经常会出现no Session的错误: 报错原因:因为懒加载在提取关联对象的属性值的时候发现E ...

  8. AirtestIDE详解(跨平台的UI自动化编辑器)

    Airtest 是网易出品的一款基于图像识别和poco控件识别的一款UI自动化测试工具. AirtestIDE 是一个跨平台.多端(Windows.web.android.ios.游戏)的UI自动化测 ...

  9. SpringBoot集成Swagger2 以及汉化 快速教程

    (一) Swagger介绍 Swagger 是一款RESTFUL接口的文档在线自动生成+功能测试功能软件 (二)为什么使用Swagger 在现在的开发过程中还有很大一部分公司都是以口口相传的方式来进行 ...

  10. Effective C++ 深入理解inline

    Effective C++ 深入理解inline inline语义 inline本义是将所调用函数用自身的函数本体替换之,免受函数调用所招致的额外开销,比宏还要不易出错:但是实际上inline的受编译 ...