[luoguP2763] 试题库问题(最大流)
2024-09-29 04:13:47
每个类别和它所有的试题连一条权值为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 ;
}
最新文章
- Kinect 总结---Kinect基本认识
- 【.NET】Nuget包,把自己的dll放在云端
- calculator
- 3 构建Mysql+heartbeat+DRBD+LVS集群应用系统系列之heartbeat的搭建
- Codeforces Round #337 (Div. 2) D. Vika and Segments 线段树 矩阵面积并
- centos6.6 安装 LXC
- mac OS X操作--快捷键
- C#的Process类的一些用法
- (转载)struts2的驱动模型
- Cocos2d-x使用iOS游戏内付费IAP(C++篇)
- 实现CodeFirst自动数据迁移无需命令
- C的陷阱和缺陷研读笔记02
- ArcEngine 9.3 学习笔记(六):图层符号化(COlorRamp,MarkerSymbol,LineSymbol,FillSymbol,TextSymbol,3DChartSymbol,使用ServerStyle符号库,FeatureRender,RasterRender)
- UVA 1386 - Cellular Automaton(循环矩阵)
- Spring 高级依赖注入方式
- redis源码分析之有序集SortedSet
- ejabberd编译更新脚本
- Python -- socket 实现服务器之间的通信
- 使用Windows任务计划程序运行Windows PowerShell脚本
- 使用SSH远程登陆Linux
热门文章
- [论文理解]SSD:Single Shot MultiBox Detector
- Array - Merge Sorted Array
- overloading and overriding
- python之golbal/nonlocal
- 用Windows Native API枚举所有句柄及查找文件句柄对应文件名的方法
- PostgreSQL学习(1)-- 安装pageinspect extension
- 【前端_js】JavaScript知识点总结
- Qt的由来和发展
- python入门:简单模拟登陆时UTF-8转换成GBK编码
- Java多线程之Deque与LinkedBlockingDeque深入分析