https://www.lydsy.com/JudgeOnline/problem.php?id=5251

https://loj.ac/problem/2477  <-可以看数据

https://www.luogu.org/problemnew/show/P4382

题面太长,请自行读完之后再看本题。

考试的时候让我伤心的一道题,分明想的就是正解结果sb般第二问没二分丢了15分。

如果b=1就是一个显然的匈牙利匹配了。

考虑b!=1也只不过就是让一个导师可以多匹配几个人而已,额外记录这个导师是否还能匹配人即可。

那么对于第一问显而易见匈牙利算法即可完成,复杂度最差就是每个人的其中一个志愿被我们遍历一遍,于是一次匈牙利是O(n*c),总共O(n^2*c)。

第二问二分答案后对这个点再匈牙利一次,实际就是清出答案和现在这个点之间的点的所有答案,而且我们已经知道了它之前的所有人的志愿和导师选择,因此大可以直接复制下来而不用重新跑一遍。

因此是O(n^2*logn*c)轻松跑过。

(至于为什么debug这么久纯粹是因为我傻,没有考虑匈牙利算法可以增广的不只有它前面的点,还可以有后面的点。)

总结:一道好题,洛谷评分虚高,实际为省选/NOI-,但是为了纪念我debug的时间之长,于是评了个NOI。

#include<cmath>
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
#include<iostream>
using namespace std;
const int N=;
inline int read(){
int X=,w=;char ch=;
while(ch<''||ch>''){if(ch=='-')w=-;ch=getchar();}
while(ch>=''&&ch<='')X=(X<<)+(X<<)+ch-'',ch=getchar();
return X*w;
}
int n,m,b[N],bb[N],s[N];
int ds[N],zy[N],dds[N],zzy[N];
int a[N][N][],len[N][N];
bool vis[N];
bool dfs(int k,int w){
for(int j=;j<=len[k][w];j++){
int u=a[k][w][j];
if(vis[u])continue;
vis[u]=;
if(b[u]){
ds[k]=u;zy[k]=w;
b[u]--;
return ;
}else{
for(int l=;l<=n;l++){//这里debug 3h+才发现。
if(l==k)continue;
if(ds[l]==u){
if(dfs(l,zy[l])){
ds[k]=u;zy[k]=w;
return ;
}
}
}
}
}
return ;
}
inline void copy(int k){
for(int i=;i<=m;i++)b[i]=bb[i];
for(int i=;i<=k;i++){
ds[i]=dds[i];
zy[i]=zzy[i];
b[ds[i]]--;
}
for(int i=k+;i<=n;i++)ds[i]=-;
return;
}
inline void work2(){
for(int i=;i<=n;i++){
if(zzy[i]<=s[i])printf("0 ");
else{
int l=,r=i-,ans=;
while(l<=r){
int mid=(l+r)>>;
bool ok=;
copy(mid-);
memset(vis,,sizeof(vis));
for(int j=;j<=s[i];j++){
if(dfs(i,j)){
ans=mid;l=mid+;
ok=;
break;
}
}
if(!ok)r=mid-;
}
printf("%d ",i-ans);
}
}
puts("");
}
inline void work1(){
for(int i=;i<=n;i++){
memset(vis,,sizeof(vis));
for(int j=;j<=m;j++){
if(!len[i][j])continue;
if(dfs(i,j))break;
}
}
for(int i=;i<=n;i++){
zzy[i]=zy[i];dds[i]=ds[i];
printf("%d ",zy[i]);
}
puts("");
}
inline void init(){
n=read(),m=read();
memset(len,,sizeof(len));
for(int i=;i<=m;i++)bb[i]=b[i]=read();
for(int i=;i<=n;i++){
zy[i]=m+;ds[i]=-;
for(int j=;j<=m;j++){
int k=read();
if(k)a[i][k][++len[i][k]]=j;
}
}
for(int i=;i<=n;i++)s[i]=read();
}
int main(){
int t=read(),c=read();
while(t--){
init();
work1();
work2();
}
return ;
}

+++++++++++++++++++++++++++++++++++++++++++

+本文作者:luyouqi233。               +

+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+

+++++++++++++++++++++++++++++++++++++++++++

BZOJ5251:[九省联考2018]劈配——题解的更多相关文章

  1. [BZOJ5251][九省联考2018]劈配(网络流)

    5251: [2018多省省队联测]劈配 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 33  Solved: 22[Submit][Status][ ...

  2. BZOJ5251 八省联考2018劈配(网络流)

    劈配,匹配,网络流.那么考虑怎么跑网络流. 先看第一问.首先套路的建出超源超汇.不用想也知道导师向汇连容量为战队人数上限的边.特别地,给出局也建一个点,向汇连容量inf的边(似乎没有必要).对于一个新 ...

  3. luogu P4382 [九省联考2018]劈配

    luogu 我记得我第一次做这道题的时候屁都不会qwq 先考虑第一问,暴力是依次枚举每个人,然后从高到低枚举志愿,枚举导师,能选就选.但是可以发现前面的人选的导师可能会导致后面的人本来可以选到这个志愿 ...

  4. [八省联考2018] 劈配 mentor

    Description 一年一度的综艺节目<中国新代码>又开始了.Zayid 从小就梦想成为一名程序员,他觉得这是一个展示自己的舞台,于是他毫不犹豫地报名了. Input 轻车熟路的Zay ...

  5. BZOJ.5251.[八省联考2018]劈配mentor(最大流)

    BZOJ 洛谷 对于每个人,每次枚举一个志愿看是否能增广即可. 对于第二问,可以保留第一问中\(n\)次增广前后的\(n\)张图,二分,在对应图上看是否能增广即可. 貌似匈牙利的某种写法比网络流优多了 ...

  6. 洛谷P4382 [八省联考2018]劈配(网络流,二分答案)

    洛谷题目传送门 说不定比官方sol里的某理论最优算法还优秀一点? 所以\(n,m\)说不定可以出到\(1000\)? 无所谓啦,反正是个得分题.Orz良心出题人,暴力有70分2333 思路分析 正解的 ...

  7. P4382 [八省联考2018]劈配

    题目链接 题意分析 受到了\(olinr\ \ julao\)的影响 写了匈牙利算法 首先 我们对于每一个人 从高到低枚举志愿 如果当前志愿的老师有剩余的话 那么我们就选 否则的话 我们看看谁的那个志 ...

  8. [九省联考2018]秘密袭击coat

    [九省联考2018]秘密袭击coat 研究半天题解啊... 全网几乎唯一的官方做法的题解:链接 别的都是暴力.... 要是n=3333暴力就完了. 一.问题转化 每个联通块第k大的数,直观统计的话,会 ...

  9. 【BZOJ5250】[九省联考2018]秘密袭击(动态规划)

    [BZOJ5250][九省联考2018]秘密袭击(动态规划) 题面 BZOJ 洛谷 给定一棵树,求其所有联通块的权值第\(k\)大的和. 题解 整个\(O(nk(n-k))\)的暴力剪剪枝就给过了.. ...

随机推荐

  1. Qt 3D Studio 1.0 Resleased

    Qt 这家伙又整出一个新东西了,Qt 3D Studio 1.0 新闻链接:https://blog.qt.io/blog/2017/11/30/qt-3d-studio-1-0-released/ ...

  2. GIt学习第一天之安装和版本库创建

    搬运自 ‘廖雪峰的官方网站’ 1.git安装 官网下载地址:https://git-scm.com/download/win   百度网盘下载地址:https://pan.baidu.com/s/1k ...

  3. Vuejs 实现简易 todoList 功能 与 组件

    todoList 结合之前 Vuejs 基础与语法 使用 v-model 双向绑定 input 输入内容与数据 data 使用 @click 和 methods 关联事件 使用 v-for 进行数据循 ...

  4. 从零开始的Python学习Episode 5——字典

    字典 字典是另一种可变容器模型,且可存储任意类型对象. 一.添加 (1)直接添加 dict={'name':'smilepup'} dict['age']=20 dict['name']='piggy ...

  5. ArcFaceDemo 第二版【C#】——视频人脸识别

    啥话不说,不用跪求,直接给下载地址:http://common.tenzont.com/comdll/arcface2demo.zip(话说附件的大小不限制,还是说我的文件太大,实际上确实有点大,60 ...

  6. LeetCode - 167. Two Sum II - Input array is sorted - O(n) - ( C++ ) - 解题报告

    1.题目大意 Given an array of integers that is already sorted in ascending order, find two numbers such t ...

  7. Linux下误删文件恢复办法

    恢复删除的文件 当误删除文件时,如果还有程序对此文件进行操作,那么可以通过lsof 命令恢复文件内容. 举例: 误删粗messages日志文件 [root@cdn ~]# cat /var/log/m ...

  8. JavaScript闭包总结

    闭包是你家庭中的第三者你在享受着第三者给你带来的便利时,而你的家庭也随时触发前所未有的危机(直男癌患者的观点);闭包是指有权访问另一个函数作用域中的变量的函数,创建闭包的常见的方式,就是在一个函数内部 ...

  9. 单源最短路——dijkstra算法

    Dijkstra算法 1.定义概览 Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止. 问 ...

  10. 记一次dll强命名冲突事件

    一  问题的出现 现在要做一个net分布式平台,平台涉及多个服务之间调用问题,最基础的莫过于sso.由于我们的sso采用了wcf一套私有框架实现,另外一个webapi服务通过接口调用sso服务.由于s ...