【解题报告】洛谷 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. vmware 10虚拟机安装ubuntu server 14.04

    -開始安装ubuntu server- 1.首先是安装系统时的语言,推荐选择English 然后安装系统 这里选择语言非常重要,我開始选择了中文,安装完毕后会乱码,所以推荐选择英文 由于在中国.所以选 ...

  2. Android首次启动时间长优化之预编译提取Odex

        提示!应用程序的安装有两种情况,第一:首次启动系统时安装.第二:系统启动完毕后安装. 本篇博文基于第一种安装场景.在系统首次启动的场景中,系统会对/system/app./system/pri ...

  3. nyoj27水池数目 (DFS)

    题目27 题目信息 执行结果 本题排行 pid=27" style="text-decoration:none; color:rgb(55,119,188)">讨论 ...

  4. 从头认识Spring-1.9 内部类注入Bean

    这一章节我们来讨论一下内部类注入Bean. 1.domain 蛋糕类:(跟前一章节的一样) package com.raylee.my_new_spring.my_new_spring.ch01.to ...

  5. MBLAST - BLAST

    There are given two strings, A and B. An expansion of some string X is a string created by adding or ...

  6. tiny4412 裸机程序 七、重定位代码到DRAM【转】

    本文转载自:http://blog.csdn.net/eshing/article/details/37116637 一.关于DRAM 上一章我们讲解了如何对代码进行重定位,但是将代码重定位到只有25 ...

  7. js如何获取某id的子标签

    思路:根据id获取父对象,然后使用childNodes获取所有子对象数组,关键代码: document.getElementById(div_id).childNodes;   // 子对象数组 实例 ...

  8. LaTeX 在线编辑器(LaTeX online editors)

    eqneditor:有强大的几乎所有常用的数学符号对应的图标形式,便于快速完成latex公式编辑且易于粘贴拷贝. 此外,更为重要的一点是,随着编辑窗口内公式的编辑,会在页面的底部,自动生成其对应的 h ...

  9. 53. 部门信息显示 EXTJS 单击树节点

    1. /** * @author sux * @time 2011-1-14 * @desc 部门信息显示 */ deptInfoGridPanel = Ext.extend(Ext.grid.Edi ...

  10. PCB SQL Server 触发器应用实例

    这里以实际例子对触发器的应用对触发器的理解与应用来得更实际 一.更新触发器(Update) 临时表:inserted表有数据(新数据)     Deleted表有数据(旧数据) 实例说明:当表更新时, ...