吐槽一下:蜜汁UKE是什么玩意?!


题目分析:

  1. 观察题面,对于给定的组卷要求,计算满足要求的组卷方案,可以发现这是一道明显的有条件二分图匹配问题,于是考虑建模。

    • 建一个超级源点,一个超级汇点;源点与试题相连,汇点与类型相连。

    • 重点是类型的题数的建模。可以从感性来理解一下,其实这有一点限流的意思,每个类型只要求有这么多的题量,不能超出,于是考虑在类型与汇点相连的时候将容量设为类型的题数,在算最大流的时候将题量限制住,就能满足题面的要求了。(希望大家能明白我的意思 \(QwQ\) )

    • 最后的图即为:超级源点与试题相连,容量为1;类型与对应的试题相连,容量为1;类型与超级汇点相连,容量为类型的题数。具体来说,超级源点 \(S\) 为节点 \(1\) ,试题为节点 \(2—n+1\),类型为节点 \(n+2—n+k+1\) 超级汇点 \(T\) 为节点 \(n+k+2\) 。

  2. 建模完成之后,考虑记录方案。

    • 因为 \(Dinic\) 算法是通过 \(Xor\;1\) 来完成正向边与反向边的转变的,故正向边的 \(e[i].to\) 为路径终点,反向边的 \(e[i\;Xor\;1].to\) 为路径起点, 所以可以通过枚举每一条边来找到相应的节点。
    • 又因为反向边的 \(e[i\;Xor\;1].v\) 的初始化为0,当 \(e[i\;Xor\;1].v\neq0\) 时,即代表这条边是最大流跑过的边,也相当于这条边被匹配了。
    • 最后排除掉超级源点与超级汇点的情况。
  3. 如果 \(Dinic\) 跑一遍下来,ans(即最大流)依然为0,则本数据没有答案(即输出"No Solution!")。


code(带详细注释):

  1. #include<bits/stdc++.h>
  2. #define Maxn 4010
  3. #define Maxm 10010
  4. #define int long long
  5. using namespace std;
  6. int k,n;
  7. inline void read(int &x)
  8. {
  9. int f=1;x=0;char s=getchar();
  10. while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
  11. while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
  12. x*=f;
  13. }
  14. int S,T;
  15. int ans=0,dep[Maxn];
  16. struct edge
  17. {
  18. int to,next,v;
  19. }e[Maxm<<1];//一定注意要开两倍空间(正反两条边)
  20. int head[Maxn],ei=1;//一定注意这里的ei为奇数
  21. void add(int x,int y,int v)
  22. {
  23. ei++;
  24. e[ei].to=y;
  25. e[ei].v=v;
  26. e[ei].next=head[x];
  27. head[x]=ei;
  28. }
  29. int bfs()
  30. {
  31. queue<int>qu;
  32. memset(dep,0,sizeof(dep));
  33. dep[S]=1;
  34. qu.push(S);
  35. while(!qu.empty())
  36. {
  37. int fr=qu.front();
  38. qu.pop();
  39. for(int i=head[fr];i;i=e[i].next)
  40. {
  41. int to=e[i].to;
  42. if(dep[to]!=0||e[i].v==0) continue;
  43. qu.push(to);
  44. dep[to]=dep[fr]+1;
  45. }
  46. }
  47. return dep[T]!=0;
  48. }
  49. int dfs(int from,int maxflow)
  50. {
  51. if(from==T) return maxflow;
  52. int flow=0;
  53. for(int i=head[from];i;i=e[i].next)
  54. {
  55. int to=e[i].to;
  56. if(dep[to]!=dep[from]+1||e[i].v==0) continue;
  57. int rst=dfs(to,min(maxflow-flow,e[i].v));
  58. if(rst==0) dep[to]=0;
  59. e[i].v-=rst;
  60. e[i^1].v+=rst;
  61. flow+=rst;
  62. if(flow==maxflow) break;
  63. }
  64. return flow;
  65. }
  66. void dinic()
  67. {
  68. while(bfs())
  69. {
  70. ans+=dfs(S,LLONG_MAX);
  71. }
  72. }
  73. signed main()
  74. {
  75. read(k),read(n);
  76. S=1,T=k+n+2;//超级源点与超级汇点
  77. for(int i=1;i<=n;i++)
  78. {
  79. add(S,i+1,1);
  80. add(i+1,S,0);
  81. //超级源点与试题相连,容量为1
  82. }
  83. for(int i=1,x;i<=k;i++)
  84. {
  85. read(x);
  86. add(i+n+1,T,x);
  87. add(T,i+n+1,0);
  88. //类型与超级汇点相连,容量为类型的题数
  89. }
  90. for(int i=1,p;i<=n;i++)
  91. {
  92. read(p);
  93. for(int j=1,x;j<=p;j++)
  94. {
  95. read(x);
  96. add(i+1,x+n+1,1);
  97. add(x+n+1,i+1,0);
  98. //类型与对应的试题相连,容量为1
  99. }
  100. }
  101. dinic();//跑dinic
  102. if(ans==0)//没有答案
  103. {
  104. puts("No Solution!");
  105. return 0;
  106. }
  107. for(int num=1;num<=k;num++)//枚举所有类型
  108. {
  109. printf("%lld:",num);
  110. for(int i=2;i<=ei;i+=2)//枚举每一条边来找到相应的节点
  111. {
  112. if(e[i].to!=S&&e[i].to!=T&&e[i^1].to!=S&&e[i^1].to!=T)//排除掉超级源点与超级汇点的情况
  113. {
  114. if(e[i^1].v!=0)//这条边已经被匹配了
  115. {
  116. if(e[i].to-n-1==num)//判断是否为当前类型
  117. {
  118. printf("%lld ",e[i^1].to-1);
  119. }
  120. }
  121. }
  122. }
  123. printf("\n");
  124. }
  125. return 0;
  126. }

网络流注意事项:

  1. 网络流关键在于建模,精髓也在建模。像本题一样的二分图匹配问题可采取我使用的建模方式:最大匹配=最大流
  2. 前向星的计数器初始化时,一定要为奇数。因为第n条边为正向边,第n+1条边为反向边,要实现 \(e[i]\) 为正向边,\(e[i\;Xor\;1]\) 为反向边,就要保证正向边的i为奇数,即计数器要初始化为奇数。
  3. 前向星边数一定要开两倍空间,因为正向边一条,反向边一条。

洛谷P2763题解的更多相关文章

  1. [洛谷P3376题解]网络流(最大流)的实现算法讲解与代码

    [洛谷P3376题解]网络流(最大流)的实现算法讲解与代码 更坏的阅读体验 定义 对于给定的一个网络,有向图中每个的边权表示可以通过的最大流量.假设出发点S水流无限大,求水流到终点T后的最大流量. 起 ...

  2. 洛谷P5759题解

    本文摘自本人洛谷博客,原文章地址:https://www.luogu.com.cn/blog/cjtb666anran/solution-p5759 \[这道题重在理解题意 \] 选手编号依次为: \ ...

  3. 关于三目运算符与if语句的效率与洛谷P2704题解

    题目描述 司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组成,地图的每一格可能是山地(用“H” 表示),也可能是平原(用“P”表示),如下图.在每一格平原地形上最 ...

  4. 洛谷 P2763 试题库问题(网络流24题之一)

    题目描述 «问题描述: 假设一个试题库中有n道试题.每道试题都标明了所属类别.同一道题可能有多个类别属性.现要从题库中抽取m 道题组成试卷.并要求试卷包含指定类型的试题.试设计一个满足要求的组卷算法. ...

  5. c++并查集配合STL MAP的实现(洛谷P2814题解)

    不会并查集的话请将此文与我以前写的并查集一同食用. 原题来自洛谷 原题 文字稿在此: 题目背景 现代的人对于本家族血统越来越感兴趣. 题目描述 给出充足的父子关系,请你编写程序找到某个人的最早的祖先. ...

  6. 洛谷P2607题解

    想要深入学习树形DP,请点击我的博客. 本题的DP模型同 P1352 没有上司的舞会.本题的难点在于如何把基环树DP转化为普通的树上DP. 考虑断边和换根.先找到其中的一个环,在上面随意取两个点, 断 ...

  7. 【洛谷】题解 P1056 【排座椅】

    题目链接 因为题目说输入保证会交头接耳的同学前后相邻或者左右相邻,所以一对同学要分开有且只有一条唯一的通道才能把他们分开. 于是可以吧这条通道累加到一个数组里面.应为题目要求纵列的通道和横列的通道条数 ...

  8. 【洛谷 P2763】 试题库问题(最大流)

    题目链接 6/23 这是网络流23题里我第一个没看题解自己写出来一遍过的.. 这题应该是最简单的模型了吧. 从源点向每个类型连一条流量为这个类型要的题数,再从每个类型向可以属于这个类型的所有试题连一条 ...

  9. [洛谷P2763]试题库问题

    题目大意:有 $k$ 种类型和 $n$ 个题目,每个题目会适应部分类型,第$i$个类型需要$s_i$的题,一道题只能满足一种类型,现要求出满足所有类型的题目的方案 题解:看到匹配,想到网络流,源点向试 ...

随机推荐

  1. 初始化mysql数据库提示缺少Data:dumper模块解决方法

    初始化默认数据库运行此命令:/usr/local/mysql/scripts/mysql_install_db --user=mysql --basedir=/usr/local/mysql/ 出现错 ...

  2. c# 开发ActiveX控件,添加事件,QT调用事件

    c# 开发 ActiveX 的过程参考我的另一篇文章 :  https://www.cnblogs.com/baqifanye/p/10414004.html 本篇讲如何 在C# 开发的ActiveX ...

  3. SCUT 125 :笔芯回文(DP)

    https://scut.online/p/125 125. 笔芯回文 题目描述 bxbx有一个长度一个字符串SS,bxbx可以对其进行若干次操作. 每次操作可以删掉一个长度为k(1 \leq k \ ...

  4. SCUT 130:对抗女巫的魔法碎片(贪心)

    https://scut.online/p/130 130. 对抗女巫的魔法碎片 题目描述 光明世界的一个国家发生动荡,女巫利用了邪恶的力量将国家的村庄都施下了咒语,好在国家还有英勇的士兵,他们正义的 ...

  5. Django项目的创建和管理

    1.主题 这部分教程主要介绍如何通过Pycharm创建.管理.运行一个Django工程.对于Django模块的相关知识大家可以参考Python社区. 2.准备环境 Django版本为2.0或更高 Py ...

  6. C语言学习书籍推荐《C陷阱与缺陷》下载

    下载地址:点我 凯尼格 (作者), 高巍 (译者) <C和C++经典著作:C陷阱与缺陷>适合有一定经验的C程序员阅读学习,即便你是C编程高手,<C和C++经典著作:C陷阱与缺陷> ...

  7. C# Linq 笛卡尔积

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  8. Node热部署插件

    一.supervisor 首先需要使用 npm 安装 supervisor(这里需要注意一点,supervisor必须安装到全局) $ npm install -g supervisor Linux ...

  9. 【小家Spring】老项目迁移问题:@ImportResource导入的xml配置里的Bean能够使用@PropertySource导入的属性值吗?

    #### 每篇一句 > 大师都是偏执的,偏执才能产生力量,妥协是没有力量的.你对全世界妥协了你就是空气.所以若没有偏见,哪来的大师呢 #### 相关阅读 [[小家Spring]详解Propert ...

  10. you-get视频下载

    项目主页 https://github.com/soimort/you-get 使用you-get库一些简单命令下载视频音乐 you-get是一个基于python3的下载器,没有客户端或者可视化工具, ...