题解 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 ...
随机推荐
- Pycharm2018永久破解的办法
Pycharm2018永久破解的具体步骤: 一.下载pycharm2018专业版 JetBrains官网:https://www.jetbrains.com/pycharm/download/#sec ...
- Docker进阶之四:镜像管理
一.什么是镜像? 简单说,Docker镜像是一个不包含Linux内核而又精简的Linux操作系统. 二.镜像从哪里来? Docker Hub是由Docker公司负责维护的公共注册中心,包含大量的容 ...
- 【转载】解析 java 按值传递还是按引用传递
原文链接 说明: (1):“在Java里面参数传递都是按值传递”这句话的意思是:按值传递是传递的值的拷贝,按引用传递其实传递的是引用的地址值,所以统称按值传递. (2):在Java里面只有基本类型和 ...
- C#工具:加密解密帮助类
using System; using System.IO; using System.Security.Cryptography; using System.Text; //加密字符串,注意strE ...
- IT企业级应⽤开发模式演化
前端研发流程 传统To B类系统的研发模式 探索 & 思考设计模式库(DPL)设计语⾔设计语⾔详解基于MVVM模式的Web框架 & UI库优化后的开发模式实现价值实践 赋能 赋能授权( ...
- 解析高德地图api获取省市区,生成最新三级联动sql表
前言: 最近项目中用到了全国省市区三级信息,但是网上找到的信息都是比较旧的信息.与现在最新的地区信息匹配不上.后来想到高德地图上可能有这些信息.所以解析了一下api接口,生成了相关省市区的sql信息. ...
- 对HTML5标签的认识(三)
这篇随笔继续来认识HTML标签.这次随笔主要是对<table>标签的认识和最近我学习到的一些标签来和大家分享. 一.<table>标签 <table>标签的作用主要 ...
- Tkinter小技巧:如何为窗口右上角的‘x’添加一个自定义的响应函数
不废话,直接上代码 import tkinter as tk from tkinter import messagebox main_window = tk.Tk() main_window.geom ...
- 006. SSO 单点登录(同域SSO/跨域SSO)
SSO 单点登录:一次登录,处处登录. 只需在一个登录认证服务下进行登录后,就可访问所有相互信任的应用 同域 SSO 1. session-cookie机制:服务端通过cookie认证客户端. 用户第 ...
- Oracle 常用Sql 语句
Oracle数据库常常被用作项目开发的数据库之一:有时隔段时间没使用就会忘记一些常用的sql语法,所以我们有必要记录下常用的sql 语句,当我们需要时可以快速找到并运用. 1 创建表空间.创建用户及授 ...