传送门

每个类别和它所有的试题连一条权值为1的边。

增加一个超级源点s,s和每个类别连一条权值为选当前类别数量的边。

增加一个超级汇点t,每个试题和t连一条权值为1的边。

求最大流即可。

——代码

 #include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#define min(x, y) ((x) < (y) ? (x) : (y))
#define N 1100
#define M 3000001 int k, n, m, cnt, s, t, sum;
int num[N], a[N][N];
int head[N], to[M], next[M], val[M], dis[N], cur[N]; inline int read()
{
int x = , f = ;
char ch = getchar();
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -;
for(; isdigit(ch); ch = getchar()) x = (x << ) + (x << ) + ch - '';
return x * f;
} inline void add(int x, int y, int z)
{
to[cnt] = y;
val[cnt] = z;
next[cnt] = head[x];
head[x] = cnt++;
} inline bool bfs()
{
int i, u, v;
std::queue <int> q;
memset(dis, -, sizeof(dis));
q.push(s);
dis[s] = ;
while(!q.empty())
{
u = q.front(), q.pop();
for(i = head[u]; i ^ -; i = next[i])
{
v = to[i];
if(val[i] && dis[v] == -)
{
dis[v] = dis[u] + ;
if(v == t) return ;
q.push(v);
}
}
}
return ;
} inline int dfs(int u, int maxflow)
{
if(u == t) return maxflow;
int i, v, d, ret = ;
for(i = cur[u]; i ^ -; i = next[i])
{
v = to[i];
if(val[i] && dis[v] == dis[u] + )
{
d = dfs(v, min(val[i], maxflow - ret));
ret += d;
cur[u] = i;
val[i] -= d;
val[i ^ ] += d;
if(ret == maxflow) return ret;
}
}
return ret;
} int main()
{
int i, j, p, x;
k = read();
n = read();
s = , t = n + k + ;
for(i = ; i <= k; i++) m += num[i] = read();
for(i = ; i <= n; i++)
{
p = read();
for(j = ; j <= p; j++) x = read(), a[x][++a[x][]] = i;
}
memset(head, -, sizeof(head));
for(i = ; i <= n; i++) add(i, t, ), add(t, i, );
for(i = ; i <= k; i++) add(s, i + n, num[i]), add(i + n, s, );
for(i = ; i <= k; i++)
for(j = ; j <= a[i][]; j++)
add(i + n, a[i][j], ), add(a[i][j], i + n, );
while(bfs())
{
for(i = s; i <= t; i++) cur[i] = head[i];
sum += dfs(s, 1e9);
}
if(sum ^ m)
{
puts("No Solution!");
return ;
}
for(i = n + ; i <= n + k; i++)
{
printf("%d:", i - n);
for(j = head[i]; j ^ -; j = next[j])
if(!val[j] && to[j] ^ s)
printf(" %d", to[j]);
puts("");
}
return ;
}

最新文章

  1. Kinect 总结---Kinect基本认识
  2. 【.NET】Nuget包,把自己的dll放在云端
  3. calculator
  4. 3 构建Mysql+heartbeat+DRBD+LVS集群应用系统系列之heartbeat的搭建
  5. Codeforces Round #337 (Div. 2) D. Vika and Segments 线段树 矩阵面积并
  6. centos6.6 安装 LXC
  7. mac OS X操作--快捷键
  8. C#的Process类的一些用法
  9. (转载)struts2的驱动模型
  10. Cocos2d-x使用iOS游戏内付费IAP(C++篇)
  11. 实现CodeFirst自动数据迁移无需命令
  12. C的陷阱和缺陷研读笔记02
  13. ArcEngine 9.3 学习笔记(六):图层符号化(COlorRamp,MarkerSymbol,LineSymbol,FillSymbol,TextSymbol,3DChartSymbol,使用ServerStyle符号库,FeatureRender,RasterRender)
  14. UVA 1386 - Cellular Automaton(循环矩阵)
  15. Spring 高级依赖注入方式
  16. redis源码分析之有序集SortedSet
  17. ejabberd编译更新脚本
  18. Python -- socket 实现服务器之间的通信
  19. 使用Windows任务计划程序运行Windows PowerShell脚本
  20. 使用SSH远程登陆Linux

热门文章

  1. [论文理解]SSD:Single Shot MultiBox Detector
  2. Array - Merge Sorted Array
  3. overloading and overriding
  4. python之golbal/nonlocal
  5. 用Windows Native API枚举所有句柄及查找文件句柄对应文件名的方法
  6. PostgreSQL学习(1)-- 安装pageinspect extension
  7. 【前端_js】JavaScript知识点总结
  8. Qt的由来和发展
  9. python入门:简单模拟登陆时UTF-8转换成GBK编码
  10. Java多线程之Deque与LinkedBlockingDeque深入分析