传送门

网络流界的一股清流啊……终于没那么变态了……

考虑一下怎么建图。对于每一个类型,我们从$S$向他连边,容量为它所需的题数,表明它要可以有这么多题,对于每一道题目,我们从它对应的类型向他连边,容量为$1$,表明他可以被对应类型选中,且只能选一次,然后在把每道题目向$T$连容量为$1$的边,表明每一道题目只能被一个类型选中。然后跑一遍最大流,对于每一个类型看一看有哪几条边是有流的,那么对应的点就是这个类型选中的点

还有注意一下……输出格式有点那啥……

  1. //minamoto
  2. #include<iostream>
  3. #include<cstdio>
  4. #include<cstring>
  5. #include<queue>
  6. #define inf 0x3f3f3f3f
  7. using namespace std;
  8. #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
  9. char buf[<<],*p1=buf,*p2=buf;
  10. inline int read(){
  11. #define num ch-'0'
  12. char ch;bool flag=;int res;
  13. while(!isdigit(ch=getc()))
  14. (ch=='-')&&(flag=true);
  15. for(res=num;isdigit(ch=getc());res=res*+num);
  16. (flag)&&(res=-res);
  17. #undef num
  18. return res;
  19. }
  20. const int N=,M=;
  21. int head[N],Next[M],ver[M],edge[M],cur[N],tot=;
  22. int dep[N],s,t,n,m,sum;
  23. queue<int> q;
  24. inline void add(int u,int v,int e){
  25. ver[++tot]=v,Next[tot]=head[u],head[u]=tot,edge[tot]=e;
  26. ver[++tot]=u,Next[tot]=head[v],head[v]=tot,edge[tot]=;
  27. }
  28. bool bfs(){
  29. while(!q.empty()) q.pop();
  30. memset(dep,-,sizeof(dep));
  31. for(int i=;i<=n+m+;++i) cur[i]=head[i];
  32. q.push(s),dep[s]=;
  33. while(!q.empty()){
  34. int u=q.front();q.pop();
  35. for(int i=head[u];i;i=Next[i]){
  36. int v=ver[i];
  37. if(dep[v]<&&edge[i]){
  38. dep[v]=dep[u]+,q.push(v);
  39. if(v==t) return true;
  40. }
  41. }
  42. }
  43. return false;
  44. }
  45. int dfs(int u,int limit){
  46. if(!limit||u==t) return limit;
  47. int flow=,f;
  48. for(int i=cur[u];i;i=Next[i]){
  49. int v=ver[i];cur[u]=i;
  50. if(dep[v]==dep[u]+&&(f=dfs(v,min(limit,edge[i])))){
  51. flow+=f,limit-=f;
  52. edge[i]-=f,edge[i^]+=f;
  53. if(!limit) break;
  54. }
  55. }
  56. return flow;
  57. }
  58. int dinic(){
  59. int flow=;
  60. while(bfs()) flow+=dfs(s,inf);
  61. return flow;
  62. }
  63. int main(){
  64. //freopen("testdata.in","r",stdin);
  65. n=read(),m=read();
  66. s=,t=n+m+;
  67. for(int i=;i<=n;++i){
  68. int e=read();sum+=e;
  69. add(s,i,e);
  70. }
  71. for(int i=n+;i<=n+m;++i){
  72. add(i,t,);
  73. int p=read();
  74. for(int j=;j<=p;++j){
  75. int k=read();
  76. add(k,i,);
  77. }
  78. }
  79. if(dinic()!=sum) return puts("No Solution!"),;
  80. for(int i=;i<=n;++i){
  81. printf("%d: ",i);
  82. for(int j=head[i];j;j=Next[j])
  83. if(!edge[j]&&ver[j])
  84. printf("%d ",ver[j]-n);
  85. putchar();
  86. }
  87. return ;
  88. }

洛谷P2763 试题库问题(最大流)的更多相关文章

  1. 洛谷P2763 试题库问题(最大流)

    题意 $n$道试题,每道题有多种类别属性 抽取$m$道题组成试卷,要求包含指定的类型 输出方案 Sol 又是一道zz网络流 我的构图长这样,$k_i$表示第$i$道试题需要的数量 #include&l ...

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

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

  3. 洛谷 P2763 试题库问题【最大流】

    s向所有类别属性连流量为当前类别属性需要的个数的边,所有题目向t连流量为1的边(表示只能选一次),所有属性向含有它的题连容量为1的边.跑一变dinic,结果小于m则无解,否则看每一个类别属性连出去的题 ...

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

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

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

    非常舒适的最大流 非常显然的建图方法,然而因为数组开小卡了很长时间 #include <iostream> #include <cstdio> #include <alg ...

  6. P2763 试题库问题(dinic)

    P2763 试题库问题 dinic 搞个虚拟源点和汇点,瞎建建边就好辣. 偷张图↓↓ 如果没满流就是无解辣 输出方案咋办呢? 枚举每种类型,蓝后枚举它们的边 如果该边被使用了(通过判断反向边的流量), ...

  7. 【题解】 P2763 试题库问题(网络流)

    P2763 试题库问题 考虑一个试题要被加入进答案的集合有什么条件? 是某种类型 只算作一次 就这两种且的限制,所以我们用串联的方式连接"类型点"和"作用点". ...

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

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

  9. 网络流问题 P2763 试题库问题

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

随机推荐

  1. Java面向对象-访问控制权限

    Java面向对象-访问控制权限 Java中,可以通过一些Java关键字,来设置访问控制权限: 主要有 private(私有), package(包访问权限),protected(子类访问权限),pub ...

  2. Jquery改变td内容为1的颜色

    Jquery改变td内容为1的颜色<table id="tb" > <tr> <td val="1">1</td> ...

  3. 16-EasyNetQ之自动订阅者

    EasyNetQ v0.7.1.30版本有了一个简单AutoSubscriber.你能够使用它很容易的去扫描指定程序集中实现了IConsume 或 IConsumeAsync接口的类,然后这个自动订阅 ...

  4. smack 监听不同packet机制

    之前做即时通讯,扒了smack源码来参考.说下其中解包后进行通知的机制. Filter类:accept(Packet packet)函数,传入packet在此函数中进行对比判断,返回true 则通过此 ...

  5. Android适配器Adapter的学习

    Android中有很多的适配器,首先看看这些适配器的继承结构 这些适配器中,BaseAdapter用的最多,也用的最熟,先放过他,从ArrayAdapter开始 一个listAdapter用来管理一个 ...

  6. 判断手机使用网络wifi 2G 3G

    ConnectivityManager cManager = (ConnectivityManager) this .getSystemService(Context.CONNECTIVITY_SER ...

  7. 【bzoj1083】[SCOI2005]繁忙的都市

    1083: [SCOI2005]繁忙的都市 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2424  Solved: 1591[Submit][Sta ...

  8. oracle级联更新与级联删除

    Oracle级联删除:可以使用外键约束来实现,建立表的主外键关系,给列设置级联删除.如下: ——创建了CLASS表,并设置ID字段为主键. -- Create tablecreate table CL ...

  9. 专题2-通过按键玩中断\2440按键中断编程lesson2

    1.程序优化 修改Makefile 把main.c里面的mmu代码复制到mmu.c并修改如下 main.c的修改 由于在bootloader当中一般不会使用MMU,所以 main.c 加入led.c文 ...

  10. KMP算法细讲(豁然开朗)

    一.KMP算法是如何针对传统算法修改的 用模式串P去匹配字符串S,在i=6,j=4时发生失配: ---------------------------------------------------- ...