luogu P2763 试题库问题
本题可以用最大流也可以用最大匹配(本质一样),用dinic最大流好建图,但码量大,匈牙利码量小,建图费点劲。
最大流:依旧是设一个源点一个汇点,对于每一个种类,连一条到汇点的边,capacity为需要的量,对于每一个试题,从源点连一条capacity为1的边到他,从他对每一个其所属的编号种类连一条capacity为1的边,求最大流即可,再找出最小割即可
- #include<bits/stdc++.h>
- using namespace std;
- #define lowbit(x) ((x)&(-x))
- typedef long long LL;
- const int maxm = 1e5+;
- const int maxn = 1e3+;
- const int INF = 0x3f3f3f3f;
- struct edge{
- int u, v, cap, flow, nex;
- } edges[maxm];
- int head[maxm], cur[maxm], cnt, level[maxn], capacity[];
- vector<int> ans[];
- void init() {
- memset(head, -, sizeof(head));
- }
- void addedge(int u, int v, int cap) {
- edges[cnt] = edge{u, v, cap, , head[u]};
- head[u] = cnt++;
- }
- void bfs(int s) {
- memset(level, -, sizeof(level));
- queue<int> q;
- level[s] = ;
- q.push(s);
- while(!q.empty()) {
- int u = q.front();
- q.pop();
- for(int i = head[u]; i != -; i = edges[i].nex) {
- edge& now = edges[i];
- if(now.cap > now.flow && level[now.v] < ) {
- level[now.v] = level[u] + ;
- q.push(now.v);
- }
- }
- }
- }
- int dfs(int u, int t, int f) {
- if(u == t) return f;
- for(int& i = cur[u]; i != -; i = edges[i].nex) {
- edge& now = edges[i];
- if(now.cap > now.flow && level[u] < level[now.v]) {
- int d = dfs(now.v, t, min(f, now.cap - now.flow));
- if(d > ) {
- now.flow += d;
- edges[i^].flow -= d;
- return d;
- }
- }
- }
- return ;
- }
- int dinic(int s, int t) {
- int maxflow = ;
- for(;;) {
- bfs(s);
- if(level[t] < ) break;
- memcpy(cur, head, sizeof(head));
- int f;
- while((f = dfs(s, t, INF)) > )
- maxflow += f;
- }
- return maxflow;
- }
- void run_case() {
- int k, n, p, u, sum = ;
- init();
- cin >> k >> n;
- int s = , t = n+k+;
- for(int i = ; i <= k; ++i) {
- cin >> capacity[i];
- sum += capacity[i];
- addedge(n+i, t, capacity[i]), addedge(t, n+i, );
- }
- for(int i = ; i <= n; ++i) {
- cin >> p;
- addedge(s, i, ), addedge(i, s, );
- while(p--) {
- cin >> u;
- addedge(i, u+n, ), addedge(u+n, i, );
- }
- }
- if(dinic(s, t) != sum) {cout << "No Solution!"; return;}
- for(int i = ; i <= n; ++i) {
- for(int j = head[i]; j != -; j = edges[j].nex) {
- if(edges[j].flow) {
- ans[edges[j].v - n].push_back(i);
- break;
- }
- }
- }
- for(int i = ; i <= k; ++i) {
- cout << i << ":";
- for(auto j : ans[i])
- cout << " " << j;
- cout << "\n";
- }
- }
- int main() {
- ios::sync_with_stdio(false), cin.tie();
- run_case();
- //cout.flush();
- return ;
- }
Dinic
匈牙利:对于每一个种类都连一条边到其所属的试卷,求最大匹配即可(无代码)
luogu P2763 试题库问题的更多相关文章
- 【题解】Luogu P2763 试题库问题
原题传送门 这题很简单啊 从源点向k类题目分别连流量为所需数量的边 从每道题向汇点连一条流量为1的边(每题只能用1次) 从类型向对应的题目连一条流量为1的边 跑一遍最大流 如果最大流小于所需题目数量, ...
- P2763 试题库问题(dinic)
P2763 试题库问题 dinic 搞个虚拟源点和汇点,瞎建建边就好辣. 偷张图↓↓ 如果没满流就是无解辣 输出方案咋办呢? 枚举每种类型,蓝后枚举它们的边 如果该边被使用了(通过判断反向边的流量), ...
- Libre 6006 「网络流 24 题」试题库 / Luogu 2763 试题库问题 (网络流,最大流)
Libre 6006 「网络流 24 题」试题库 / Luogu 2763 试题库问题 (网络流,最大流) Description 问题描述: 假设一个试题库中有n道试题.每道试题都标明了所属类别.同 ...
- 【题解】 P2763 试题库问题(网络流)
P2763 试题库问题 考虑一个试题要被加入进答案的集合有什么条件? 是某种类型 只算作一次 就这两种且的限制,所以我们用串联的方式连接"类型点"和"作用点". ...
- 网络流问题 P2763 试题库问题
题目描述 «问题描述: 假设一个试题库中有n道试题.每道试题都标明了所属类别.同一道题可能有多个类别属性.现要从题库中抽取m 道题组成试卷.并要求试卷包含指定类型的试题.试设计一个满足要求的组卷算法. ...
- 洛谷 P2763 试题库问题(网络流24题之一)
题目描述 «问题描述: 假设一个试题库中有n道试题.每道试题都标明了所属类别.同一道题可能有多个类别属性.现要从题库中抽取m 道题组成试卷.并要求试卷包含指定类型的试题.试设计一个满足要求的组卷算法. ...
- [洛谷P2763]试题库问题
题目大意:有 $k$ 种类型和 $n$ 个题目,每个题目会适应部分类型,第$i$个类型需要$s_i$的题,一道题只能满足一种类型,现要求出满足所有类型的题目的方案 题解:看到匹配,想到网络流,源点向试 ...
- 洛谷P2763 试题库问题(最大流)
题意 $n$道试题,每道题有多种类别属性 抽取$m$道题组成试卷,要求包含指定的类型 输出方案 Sol 又是一道zz网络流 我的构图长这样,$k_i$表示第$i$道试题需要的数量 #include&l ...
- P2763 试题库问题 (网络流 最大流)
传送门 解题思路 比较简单的网络流,建图还是比较好想的.让源点向试题连流量为1的边,试题向所属类型连流量为1的边,类型向汇点连流量为需要此类试题的边.直接跑最大流,输出答案时找到那些满流的边所对的点. ...
随机推荐
- 吴裕雄--天生自然Numpy库学习笔记:NumPy 统计函数
NumPy 提供了很多统计函数,用于从数组中查找最小元素,最大元素,百分位标准差和方差等. numpy.amin() 用于计算数组中的元素沿指定轴的最小值. numpy.amax() 用于计算数组中的 ...
- 炼金术(2): 为什么要用issue管理软件
在项目开发中,存在的无数的任务分解,问题管理,流程跟踪.因为直接说话或者直接在IM里喊话是很容易的,所以在一个还没有习惯使用issue管理软件的团队中,直接说话或者直接在IM里AT,就在某些时候变成了 ...
- 安装Ubuntu后的一些配置
Ubuntu安装的一些配置 搜狗拼音的安装 卸载ibus和它的配置, 卸载顶部面板的键盘指示 sudo apt remove ibus sudo apt purge ibus sudo apt rem ...
- ArrayQueue(队列)
code1: #include <stdio.h> #include <conio.h> #include <stdlib.h> #define MAXSIZE 6 ...
- Trie学习总结
Trie树学习总结 字典树,又称前缀树,是用于快速处理字符串的问题,能做到快速查找到一些字符串上的信息. 另外,Trie树在实现高效的同时,会损耗更多的空间,所以Trie是一种以空间换时间的算法. T ...
- 使用pyinstaller打包.py程序
使用pyinstaller打包.py程序 例如打包D:/Desktop 目录下的 filename.py 文件 打开 cmd 将目录切换至 D:/Desktop 输入命令 pyinstaller -F ...
- Qt5.5 使用smtp发邮件的各种坑
本人刚开始学习C++,用的是Qt5.5的IED,经过了两天的学习和查找资料,终于成功发了第一封邮件.以163邮箱为例,简单总结一下. 1.设置邮箱 这一步比较关键,要开通smtp服务,在开通的过程中会 ...
- 【PAT甲级】1035 Password (20 分)
题意: 输入一个正整数N(<=1000),接着输入N行数据,每行包括一个ID和一个密码,长度不超过10的字符串,如果有歧义字符就将其修改.输出修改过多少组密码并按输入顺序输出ID和修改后的密码, ...
- windows通过zip安装mysql5.7.26的一个坑
需要将my.ini的 红框的/不能写成\ 注意编码格式问题 然后 mysqld --initialize-insecure mysqld --install net start mysql
- Java-用星号打印菱形
打印如图所示菱形9行9列(提示可以将菱形分成上下两个三角形,分析每行空格数和星号个数的关系) 代码如下: package com.homework.lhh; public class Ex20 { p ...