题解 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 ...
 
随机推荐
- 使用 ASP.NET Core MVC 创建 Web API(三)
			
使用 ASP.NET Core MVC 创建 Web API 使用 ASP.NET Core MVC 创建 Web API(一) 使用 ASP.NET Core MVC 创建 Web API(二) 十 ...
 - 在vue项目中添加全局提示框
			
1.写一个提示框组件:msg.vue (注明:这里用两个div的原因是成功和失败的提示不能用同一个div,因为他们可能紧接着出现,所以不能从始至终只有一个提示框在工作) 2.写一个调用此组建的js : ...
 - 图像检索(2):均值聚类-构建BoF
			
在图像检索时,通常首先提取图像的局部特征,这些局部特征通常有很高的维度(例如,sift是128维),有很多的冗余信息,直接利用局部特征进行检索,效率和准确度上都不是很好.这就需要重新对提取到的局部特征 ...
 - jmFidExt - Fiddler 代理插件
			
本插件作用是把某些请求代理到指定的IP(端号)或文件,设置简便. 源码地址:https://github.com/jiamao/jmFidExt 示图 安装 下载代码,用开发工具vs2003及以上的版 ...
 - Linux高级运维 第三章  Linux基本命令操作
			
3.1 Linux终端介绍.Shell提示符.Bash基本语法 3.1.1 登录LINUX终端 两种终端仿真器:1.GNOME桌面的GHOME Terminal : 2.KDE桌面的Konsole ...
 - MYSQL  SQL语句优化
			
1.EXPLAIN 做MySQL优化,我们要善用EXPLAIN查看SQL执行计划. 下面来个简单的示例,标注(1.2.3.4.5)我们要重点关注的数据: type列,连接类型.一个好的SQL语句至少要 ...
 - dubbo 2.7.0 中缺乏 <dubbo:annotation /> 的解决方案
			
一.背景 从 dubbo 2.6.5 升级到 2.7.0,突然发现好多地方不能用了,dubbo:annotation 直接报红,原先的 @Service 和 @Reference 中直接报了过时,源 ...
 - 折腾Java设计模式之观察者模式
			
观察者模式 Define a one-to-many dependency between objects where a state change in one object results in ...
 - IDEA 安装配置可视化 MongDB 插件
			
IDEA 安装配置可视化 MongDB 插件 1.安装MongoDB插件 打开 IDEA ,file --> settings --> plugins,在右边搜索栏中输入Mongo,点击 ...
 - Jinja2用法总结
			
Jinja2用法总结 一:渲染模版 要渲染一个模板,通过render_template方法即可. @app.route('/about/') def about(): # return rende ...