题解 P2763 【试题库问题】
这题可以用网络流,但我用的是匈牙利算法
进入正题
- 设第
个类型需要
个.将每个类型拆成
个点,用一个边集数组记录它拆成的点。 - 第
个试题有
个类型,分别将
与
拆成的点连边,这样便构成了一个二分图。 - 使用匈牙利算法计算最大匹配,若最大匹配小于
的总数,则无解。 - 输出时使用优先队列。
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 ...
随机推荐
- Window环境下搭建Git服务器
如果公司要搭建自己的 Git 服务器,可以使用 gitblit 这个开源的 Git 服务器 下载gitblit安装包 到 http://gitblit.com/下载安装包 解压缩下载的压缩包即可,无需 ...
- 值得一看的35个Redis常用问题总结
1.什么是redis? Redis 是一个基于内存的高性能key-value数据库. 2.Reids的特点 Redis本质上是一个Key-Value类型的内存数据库,很像memcached,整个数据库 ...
- Lumen框架—升级改造之路-开篇
一.前言 首先,我先阐述下,为什么要做这件事.lumen是一款比较轻型的PHP框架,但是,作为项目开发来说,它还是缺少很多东西,比如Response返回值规范的自定义,异常抛出格式的自定义,以及 ...
- VUE v-for问题
今天写一个拖动然后使装备交换的功能,在背包格子里 发现直接设置Bags数组的项,v-for渲染出来的列表不会对应改变,只有设置值才会改变 有点拗口,贴代码吧 var repear = this.Bag ...
- ajax验证用户名是否存在
jsp页面 <head> <script type="text/javascript" src="js/register.js">< ...
- webpack4.x笔记-配置基本的前端开发环境(一)
webpack的基本使用 webpack 本质上是一个打包工具,它会根据代码的内容解析模块依赖,帮助我们把多个模块的代码打包.借用 webpack 官网的图片: 虽然webpack4.x的版本可以零配 ...
- Python数据挖掘
Python之所以如此流行,原因在于它的数据分析和挖掘方面表现出的高性能,而我们前面介绍的Python大都集中在各个子功能(如科学计算.矢量计算.可视化等),其目的在于引出最终的数据分析和数据挖掘功能 ...
- 亿级流量场景下,大型架构设计实现【2】---storm篇
承接之前的博:亿级流量场景下,大型缓存架构设计实现 续写本博客: ****************** start: 接下来,我们是要讲解商品详情页缓存架构,缓存预热和解决方案,缓存预热可能导致整个系 ...
- zoomeye搜索+用selenium实现对佳能打印机的爬虫
本文仅用于学习参考.要遵纪守法哦! 目的:找出一台佳能打印机,得到它的日志文件,并利用其远程打印. 1.先用zoomeye找一个打印机出来,搜索语句:printer +country:"CN ...
- SQLServer之多表联合查询
多表联合查询简介 定义:连接查询是关系型数据库最主要的查询,通过连接运算符可以实现多个表连接数据查询. 分类:内连接,外连接,全外连接. 内连接 定义 内联接使用比较运算符根据每个表的通用列中的值匹配 ...