这题可以用网络流,但我用的是匈牙利算法


进入正题

  • 设第个类型需要个.将每个类型拆成个点,用一个边集数组记录它拆成的点。
  • 个试题有个类型,分别将拆成的点连边,这样便构成了一个二分图。
  • 使用匈牙利算法计算最大匹配,若最大匹配小于的总数,则无解。
  • 输出时使用优先队列。

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 【试题库问题】的更多相关文章

  1. 【题解】 P2763 试题库问题(网络流)

    P2763 试题库问题 考虑一个试题要被加入进答案的集合有什么条件? 是某种类型 只算作一次 就这两种且的限制,所以我们用串联的方式连接"类型点"和"作用点". ...

  2. P2763 试题库问题(dinic)

    P2763 试题库问题 dinic 搞个虚拟源点和汇点,瞎建建边就好辣. 偷张图↓↓ 如果没满流就是无解辣 输出方案咋办呢? 枚举每种类型,蓝后枚举它们的边 如果该边被使用了(通过判断反向边的流量), ...

  3. 网络流问题 P2763 试题库问题

    题目描述 «问题描述: 假设一个试题库中有n道试题.每道试题都标明了所属类别.同一道题可能有多个类别属性.现要从题库中抽取m 道题组成试卷.并要求试卷包含指定类型的试题.试设计一个满足要求的组卷算法. ...

  4. 洛谷 P2763 试题库问题(网络流24题之一)

    题目描述 «问题描述: 假设一个试题库中有n道试题.每道试题都标明了所属类别.同一道题可能有多个类别属性.现要从题库中抽取m 道题组成试卷.并要求试卷包含指定类型的试题.试设计一个满足要求的组卷算法. ...

  5. 【题解】Luogu P2763 试题库问题

    原题传送门 这题很简单啊 从源点向k类题目分别连流量为所需数量的边 从每道题向汇点连一条流量为1的边(每题只能用1次) 从类型向对应的题目连一条流量为1的边 跑一遍最大流 如果最大流小于所需题目数量, ...

  6. [洛谷P2763]试题库问题

    题目大意:有 $k$ 种类型和 $n$ 个题目,每个题目会适应部分类型,第$i$个类型需要$s_i$的题,一道题只能满足一种类型,现要求出满足所有类型的题目的方案 题解:看到匹配,想到网络流,源点向试 ...

  7. 洛谷P2763 试题库问题(最大流)

    题意 $n$道试题,每道题有多种类别属性 抽取$m$道题组成试卷,要求包含指定的类型 输出方案 Sol 又是一道zz网络流 我的构图长这样,$k_i$表示第$i$道试题需要的数量 #include&l ...

  8. P2763 试题库问题 (网络流 最大流)

    传送门 解题思路 比较简单的网络流,建图还是比较好想的.让源点向试题连流量为1的边,试题向所属类型连流量为1的边,类型向汇点连流量为需要此类试题的边.直接跑最大流,输出答案时找到那些满流的边所对的点. ...

  9. luogu P2763 试题库问题

    本题可以用最大流也可以用最大匹配(本质一样),用dinic最大流好建图,但码量大,匈牙利码量小,建图费点劲. 最大流:依旧是设一个源点一个汇点,对于每一个种类,连一条到汇点的边,capacity为需要 ...

  10. 洛谷 [P2763]试题库问题

    非常舒适的最大流 非常显然的建图方法,然而因为数组开小卡了很长时间 #include <iostream> #include <cstdio> #include <alg ...

随机推荐

  1. jdk切换小工具

    今天无意之中看到一个小工具,就是可以自由切换jdk版本!以前每次切换jdk还要去找环境变量找半天,emmm.... 现在我们只需要双击一个xxx.bat的一个批处理文件,就可以自由切换jdk版本,很方 ...

  2. 学习ASP.NET Core Razor 编程系列十二——在页面中增加校验

    学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...

  3. Ocelot-基于.NET Core的开源网关实现

    写在前面 API网关是系统内部服务暴露在外部的一个访问入口,类似于代理服务器,就像一个公司的门卫承担着寻址.限制进入.安全检查.位置引导等工作,我们可以形象的用下图来表示: 外部设备需要访问内部系统服 ...

  4. .NET Core和Swagger 生成 Api 文档

    测试/生产环境的BUG 这里更新一下在本地调试正常,在INT/PROD上抛错,错误信息为: */**/*.xml(Swagger json file) 文件找不到,在startup 里builder ...

  5. 简单介绍shell编程四剑客之grep

    概要:分别的作用 grep:文本过滤(模式:pattern)工具,grep,egrep,fgrep,擅长过滤. sed:stream editor 文本编辑工具:(流编辑器),擅长取行.替换. awk ...

  6. c# List根据某个属性进行分类,变成以属性名称作为分类的多个List

    在平时的开发中,我们从数据库中得到List列表,但是我们希望可以根据属性名称再次进行分类. 其实LINQ中已经内置相应的算法. 长话短说,直接上代码: var dataList = JsonHelpe ...

  7. 个人对【依赖倒置(DIP)】、【控制反转(IOC)】、【依赖注入(DI)】浅显理解

    一.依赖倒置(Dependency Inversion Principle) 依赖倒置是面向对象设计领域的一种软件设计原则.(其他的设计原则还有:单一职责原则.开放封闭原则.里式替换原则.接口分离原则 ...

  8. 解决vue数据渲染过程中的闪动问题

    关键代码 主要解决vue双大括号{{}}在数据渲染和加载过程中的闪动问题,而影响客服体验. html代码: <span class="tableTitle selftab" ...

  9. CSS3文字与字体 text-overflow 与 word-wrap

    text-overflow 对象内的文本溢出部分采用省略“...”标记 或者 剪切: text-overflow:elip(超出容器边界的内容剪切掉)  | ellipsis(超出容器边界内容省略标示 ...

  10. iOS----------Xcode 无线调试

    环境要求: 至少Mac OSX 10.12.6 iOS 11 Xcode 9 1. ”自己的工程“ -> windows -> Device and Simulators ,打开设备和模拟 ...