这题可以用网络流,但我用的是匈牙利算法
进入正题
- 设第个类型需要个.将每个类型拆成个点,用一个边集数组记录它拆成的点。
- 第个试题有个类型,分别将与拆成的点连边,这样便构成了一个二分图。
- 使用匈牙利算法计算最大匹配,若最大匹配小于的总数,则无解。
- 输出时使用优先队列。
OK了!!!
code:
- 拆点:
int main()
{
for (int i=1;i<=k;i++)
{
need[i]=read();
for (int j=1;j<=need[i];j++)Addedge(0,i,++cnt);
}
}
- 将试题与类型连边:
void dot(int u,int v)
{
for (int k=head[v];k>0;k=set[k].nx)
Addedge(u,set[k].v);
return ;
} int main()
{
int p;
for (int i=1;i<=n;i++)
{
p=read();
for (int j=1;j<=p;j++)dot(i,read());
}
}
- 匈牙利算法:
bool dfs(int u)
{
int v;
for (int k=head[1][u];k>0;k=set[1][k].nx)
{
v=set[1][k].v;
if (!vis[v])
{
vis[v]=true;
if ((match[v]==-1)||dfs(match[v]))
{
match[v]=u;return true;
}
}
}
return false;
}
- 输出:
priority_queue<int,vector<int>,greater<int> > Q;
int main()
{
for (int i=1;i<=k;i++)
{
printf("%d: ",i);
for (int j=head[0][i];j>0;j=set[0][j].nx)Q.push(match[set[0][j].v]);
while (!Q.empty()){printf("%d ",Q.top());Q.pop();}
printf("\n");
}
}
-
总代码:
#include <functional>
#include <cstdio>
#include <bitset>
#include <queue>
using namespace std; int read()
{
int x=0,f=1;char c=getchar();
while (c<'0' || c>'9'){if (c=='-')f=-1;c=getchar();}
while (c>='0'&&c<='9'){x=(x<<3)+(x<<1)+c-48;c=getchar();}
return x*f;
} const int MAXK=25;
const int MAXN=1010;
int n,k,cnt; struct edge
{
int v,nx;
}set[2][MAXN*MAXN];
int id[2];
int head[2][MAXN];
int need[MAXK],match[MAXN*MAXN];
bitset<MAXN> vis;
priority_queue<int,vector<int>,greater<int> > Q; inline void Addedge(int loca,int u,int v)
{
id[loca]++;set[loca][id[loca]].v=v;set[loca][id[loca]].nx=head[loca][u];
head[loca][u]=id[loca];
} inline void dot(int u,int v)
{
for (int k=head[0][v];k>0;k=set[0][k].nx)
Addedge(1,u,set[0][k].v);
return ;
} inline bool dfs(int u)
{
int v;
for (int k=head[1][u];k>0;k=set[1][k].nx)
{
v=set[1][k].v;
if (!vis[v])
{
vis[v]=true;
if ((match[v]==-1)||dfs(match[v]))
{
match[v]=u;return true;
}
}
}
return false;
} int main()
{
k=read();n=read();
for (int i=1;i<=k;i++)
{
need[i]=read();
for (int j=1;j<=need[i];j++)Addedge(0,i,++cnt);
}
int p;
for (int i=1;i<=n;i++)
{
p=read();
for (int j=1;j<=p;j++)dot(i,read());
}
int ans=0;
for (int i=1;i<=cnt;i++)match[i]=-1;
for (int i=1;i<=n;i++)
{
vis.reset();
if (dfs(i))ans++;
}
if (ans<cnt)puts("No Solution!");
else
{
for (int i=1;i<=k;i++)
{
printf("%d: ",i);
for (int j=head[0][i];j>0;j=set[0][j].nx)Q.push(match[set[0][j].v]);
while (!Q.empty()){printf("%d ",Q.top());Q.pop();}
printf("\n");
}
}
return 0;
}
//丑代码
点赞吧
题解 P2763 【试题库问题】的更多相关文章
-
【题解】 P2763 试题库问题(网络流)
P2763 试题库问题 考虑一个试题要被加入进答案的集合有什么条件? 是某种类型 只算作一次 就这两种且的限制,所以我们用串联的方式连接"类型点"和"作用点". ...
-
P2763 试题库问题(dinic)
P2763 试题库问题 dinic 搞个虚拟源点和汇点,瞎建建边就好辣. 偷张图↓↓ 如果没满流就是无解辣 输出方案咋办呢? 枚举每种类型,蓝后枚举它们的边 如果该边被使用了(通过判断反向边的流量), ...
-
网络流问题 P2763 试题库问题
题目描述 «问题描述: 假设一个试题库中有n道试题.每道试题都标明了所属类别.同一道题可能有多个类别属性.现要从题库中抽取m 道题组成试卷.并要求试卷包含指定类型的试题.试设计一个满足要求的组卷算法. ...
-
洛谷 P2763 试题库问题(网络流24题之一)
题目描述 «问题描述: 假设一个试题库中有n道试题.每道试题都标明了所属类别.同一道题可能有多个类别属性.现要从题库中抽取m 道题组成试卷.并要求试卷包含指定类型的试题.试设计一个满足要求的组卷算法. ...
-
【题解】Luogu P2763 试题库问题
原题传送门 这题很简单啊 从源点向k类题目分别连流量为所需数量的边 从每道题向汇点连一条流量为1的边(每题只能用1次) 从类型向对应的题目连一条流量为1的边 跑一遍最大流 如果最大流小于所需题目数量, ...
-
[洛谷P2763]试题库问题
题目大意:有 $k$ 种类型和 $n$ 个题目,每个题目会适应部分类型,第$i$个类型需要$s_i$的题,一道题只能满足一种类型,现要求出满足所有类型的题目的方案 题解:看到匹配,想到网络流,源点向试 ...
-
洛谷P2763 试题库问题(最大流)
题意 $n$道试题,每道题有多种类别属性 抽取$m$道题组成试卷,要求包含指定的类型 输出方案 Sol 又是一道zz网络流 我的构图长这样,$k_i$表示第$i$道试题需要的数量 #include&l ...
-
P2763 试题库问题 (网络流 最大流)
传送门 解题思路 比较简单的网络流,建图还是比较好想的.让源点向试题连流量为1的边,试题向所属类型连流量为1的边,类型向汇点连流量为需要此类试题的边.直接跑最大流,输出答案时找到那些满流的边所对的点. ...
-
luogu P2763 试题库问题
本题可以用最大流也可以用最大匹配(本质一样),用dinic最大流好建图,但码量大,匈牙利码量小,建图费点劲. 最大流:依旧是设一个源点一个汇点,对于每一个种类,连一条到汇点的边,capacity为需要 ...
-
洛谷 [P2763]试题库问题
非常舒适的最大流 非常显然的建图方法,然而因为数组开小卡了很长时间 #include <iostream> #include <cstdio> #include <alg ...
随机推荐
-
[LeetCode] Strobogrammatic Number II 对称数之二
A strobogrammatic number is a number that looks the same when rotated 180 degrees (looked at upside ...
-
CSS3总结 (帅哥)
第1章CSS3简介 如同人类的的进化一样,CSS3是CSS2的"进化"版本,在CSS2基础上,增强或新增了许多特性, 弥补了CSS2的众多不足之处,使得Web开发变得更为高效和便捷 ...
-
EAPOL 协议
EAPOL 协议 一.基本概念 EAPOL 的全称为 Extensible Authentication Protocol Over LAN,即 EAP Over Lan,也即基于局域网的扩展认证协议 ...
-
毕向东JAVA视频讲解(第六课)
用java语言对现实生活中的事物进行描述. 通过类的形式来体现的. 怎么描述呢? 对于事物描述通常只关注两方面. 一个是属性,一个是行为. 只要明确该事物的属性和行为并定义在类中即可. 对象:其实就是 ...
-
使用 Python 的 SQLite JSON1 和 FTS5 扩展
早在九月份,编程界出现一个名为 json1.c 的文件,此前这个文件一直在 SQLite 的库里面.还有,笔者也曾总结通过使用新的 json1 扩展来编译 pysqlite 的技巧.但现在随着 SQL ...
-
cocod2d-x 之 HelloWorld
cocos2d-x 2.2创建项目 进入cocos2d-x-2.2/tools/project-creator,运行命令 python create_project.py -project MyGam ...
-
jQuery代码优化 事件委托篇
<转自 http://www.jb51.net/article/28770.htm> 参考文章: 解密jQuery事件核心 - 绑定设计(一) 参考文章: 解密jQuery事件核心 - ...
-
第4章 流程控制----编写Java程序,应用for循环打印菱形
package four; public class fouroneone { public static void main(String args[]){ ;i<=;i+=){ ;kong& ...
-
ionic3 调用摄像头 当键盘弹出时候 出现摄像头 背景
iOS 端毫无 bug,Android 端却出现了问题.当软键盘弹出后,Android 端的 tabs 移到了软键盘的上面,再仔细一看,整个界面都被压扁了,输入框也不知道去哪儿了. 于是去翻 Ioni ...
-
使用Rider写一个C#的Hello World程序
1. 安装Rider 首先到Jetbrains官网下载Rider:https://www.jetbrains.com/rider/ 然后到IntelliJ IDEA 注册码获得注册码. 2. 安装do ...