劈配 [多省省选] [BZOJ5251] [网络流]
分析:
这道题看题都看了我好久...
我们可以容易想到这道题和网络流有关。
首先,从原点向每个学员连一条流量为1的边
然后,要限制每个导师的学员,在每个导师连到汇点的时候流量限制为bi
再接着,按照学员的顺序一个个动态加边,一次性加入同样优先级的边,如果有增广路就记录答案。
(第一问完美解决)
然后第二问怎么做呢?
对于一个学员,如果已经确定了排位,那我们很容易的就能验证是不是满足他的要求。
那么我们就能在[1,i-1]的区间里二分答案去检验,在[1,now-1]的残余网络里面跑即可(注意加上他自己要求范围内的边)
如何优化?
第一问:如果把整个网络都加进去的话边数太多很可能会T,而我们发现有很多边是没用的->不能提供增广路的边
那我们在跑完一个优先级发现找不到增广路的时候就把这些边全删掉。
第二问:显然,二分答案每次都建立残余网络是一个很大的工程,我们可以在第一问依次处理时把残余网络图给存下来,第二问直接用即可。
Code
#include<bits/stdc++.h>
#define RG register int
#define rep(i,a,b) for(RG i=a;i<=b;++i)
#define per(i,a,b) for(RG i=a;i>=b;--i)
#define ll long long
#define inf (1<<29)
#define maxn 210
#define maxm 10010
using namespace std;
int p,c,n,m,cnt,S,T;
int tmph[maxn][maxn<<],head[maxn<<],hd[maxn<<],step[maxn<<],ans[maxn],cntt[maxn];
int a[maxn][maxn],Ex[maxn],lmp[maxn][maxn],level[maxn],deal[maxn][maxn][];
struct E{
int u,v,next,pre,fl;
}e[maxm],tmpe[maxn][maxm]; inline int read()
{
int x=,f=;char c=getchar();
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
} void init()
{
memset(lmp,,sizeof(lmp));
memset(head,,sizeof(head));
cnt=;
} inline void del(int i)
{
if(e[i].next) e[e[i].next].pre=e[i].pre;
if(e[i].pre) e[e[i].pre].next=e[i].next;
if(i==head[e[i].u]) head[e[i].u]=e[i].next;
} inline void add(int u,int v,int w)
{
e[++cnt].v=v,e[cnt].u=u,e[cnt].next=head[u];
if(head[u]) e[head[u]].pre=cnt;
head[u]=cnt,e[cnt].fl=w; swap(u,v); e[++cnt].v=v,e[cnt].u=u,e[cnt].next=head[u];
if(head[u]) e[head[u]].pre=cnt;
head[u]=cnt,e[cnt].fl=;
} inline void add2(int u,int v,int w)
{
e[++cnt].v=v,e[cnt].next=head[u],head[u]=cnt,e[cnt].fl=w; swap(u,v);
e[++cnt].v=v,e[cnt].next=head[u],head[u]=cnt,e[cnt].fl=;
} bool bfs()
{
queue<int> que;
memset(step,,(T<<)+);memcpy(hd,head,(T<<)+);
que.push(S),step[S]=;
RG u,v;
while(!que.empty())
{
u=que.front(),que.pop();
for(RG i=head[u];i;i=e[i].next)
{
v=e[i].v;
if(e[i].fl&&!step[v]) step[v]=step[u]+,que.push(v);
}
}
return step[T];
} int dfs(int u,int fl)
{
if(u==T) return fl;
int tp,tt=;
for(RG &i=hd[u];i;i=e[i].next){
int v=e[i].v;
if(e[i].fl&&step[v]==step[u]+)
{
tp=dfs(e[i].v,min(e[i].fl,fl));
tt+=tp;
e[i].fl-=tp;
e[i^].fl+=tp;
if(tt==fl) return tt;
}
}
if(tt!=fl) step[u]=-;
return tt;
} void work1()
{
RG l;
rep(i,,n)
{
ans[i]=m+,add(S,i,);
rep(j,,m)
{
if(!lmp[i][j]) continue;
l=cnt;
rep(k,,lmp[i][j]) add(i,deal[i][j][k]+n,);
if(bfs()&&dfs(S,inf)) {ans[i]=j;break;}
else {rep(k,l,cnt) del(k);cnt=l;}
}
rep(j,,T) tmph[i][j]=head[j];
rep(j,,cnt) tmpe[i][j]=e[j];
cntt[i]=cnt;
}
rep(i,,n) printf("%d ",ans[i]);puts("");
} bool judge(int u,int w)
{
cnt=cntt[w-];
rep(i,,T) head[i]=tmph[w-][i];
rep(i,,cnt) e[i]=tmpe[w-][i]; add(S,u,); rep(i,,Ex[u])
{
if(!lmp[u][i]) continue;
rep(j,,lmp[u][i]) add2(u,deal[u][i][j]+n,);
} return (bfs()&&dfs(S,inf));
} void input()
{
n=read(),m=read();
S=n+m+,T=n+m+;
rep(i,,m)
{
level[i]=read();
add(i+n,T,level[i]);
}
cntt[]=cnt;
rep(i,,cnt) tmpe[][i]=e[i];
rep(i,,T) tmph[][i]=head[i];
rep(i,,n) rep(j,,m)
{
a[i][j]=read(); if(!a[i][j]) continue;
deal[i][a[i][j]][++lmp[i][a[i][j]]] = j;
}
rep(i,,n) Ex[i]=read();
} void work2()
{
RG l,r,mid,ans2;
rep(i,,n)
{
if(ans[i]<=Ex[i]){printf("0 ");continue;}
l=,r=i-,ans2=;
while(l<=r)
{
mid=l+r>>;
if(judge(i,mid)) ans2=mid,l=mid+;
else r=mid-;
}
printf("%d ",i-ans2);
}
puts("");
} int main()
{
freopen("mentor.in","r",stdin);
freopen("mentor.out","w",stdout);
int TT,C;
TT=read(),C=read();
while(TT--)
{
init();
input();
work1();
work2();
}
return ;
}
劈配 [多省省选] [BZOJ5251] [网络流]的更多相关文章
- 【BZOJ5251】【八省联考2018】劈配(网络流,二分答案)
[BZOJ5251][八省联考2018]劈配(网络流,二分答案) 题面 洛谷 BZOJ Description 一年一度的综艺节目<中国新代码>又开始了. Zayid从小就梦想成为一名程序 ...
- BZOJ5251 八省联考2018劈配(网络流)
劈配,匹配,网络流.那么考虑怎么跑网络流. 先看第一问.首先套路的建出超源超汇.不用想也知道导师向汇连容量为战队人数上限的边.特别地,给出局也建一个点,向汇连容量inf的边(似乎没有必要).对于一个新 ...
- [BZOJ5251][九省联考2018]劈配(网络流)
5251: [2018多省省队联测]劈配 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 33 Solved: 22[Submit][Status][ ...
- [BZOJ5251][多省联测2018]劈配
bzoj luogu sol 从前往后依次加边,每次对一个人做完劈配后就把当前这个残余网络存下来.这样第二问就可以二分排在第几名然后check一下在对应排名的残余网络上还能不能再增广. 给网络流开结构 ...
- bzoj千题计划321:bzoj5251: [2018多省省队联测]劈配(网络流 + 二分)
https://www.lydsy.com/JudgeOnline/problem.php?id=5251 第一问: 左边一列点代表学生,右边一列点代表导师 导师向汇点连流量为 人数限制的 边 然后从 ...
- 洛谷P4382 [八省联考2018]劈配(网络流,二分答案)
洛谷题目传送门 说不定比官方sol里的某理论最优算法还优秀一点? 所以\(n,m\)说不定可以出到\(1000\)? 无所谓啦,反正是个得分题.Orz良心出题人,暴力有70分2333 思路分析 正解的 ...
- bzoj5251 [2018多省省队联测]劈配
直接网络流模拟即可AC. 可持久化+暴力=90分, 可持久化+二分=30分, 暴力加边+二分=100分. 我也很无奈啊. Ivan便涨红了脸,额上的青筋条条绽出,争辩道,“memcpy也是可持久化…… ...
- BZOJ5251:[九省联考2018]劈配——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=5251 https://loj.ac/problem/2477 <-可以看数据 https: ...
- bzoj 5251: [2018多省省队联测]劈配
Description 一年一度的综艺节目<中国新代码>又开始了. Zayid从小就梦想成为一名程序员,他觉得这是一个展示自己的舞台,于是他毫不犹豫地报名了. 题目描述 轻车熟路的Zayi ...
随机推荐
- nginx 监控脚本
[root@Client_Download_Source shell]# cat start.nginx.sh #!/bin/bash while true do sleep 2 check=`net ...
- Android Studio 修改包名最便捷做法
Android Studio,咱们开发安卓的利器,自推出就受到移动开发者的追捧,但一路走来,大家谈到他,充满了兴奋之情之余,也略显羞涩.随版本自推出以来,不断完善BUG,但咱们还是深深地踩了进去,说多 ...
- 安装淘宝npm(cnpm)
https://www.cnblogs.com/yominhi/p/7039795.html http://npm.taobao.org/ 初始化一个 mpvue 项目 现代前端开发框架和环境都是需要 ...
- javascript 语句和严格模式(三)
一.语句 javascript程序由语句组成,语句遵守特定的语法规则. block break continue empty if...else switch try catch var functi ...
- Java集合源码学习(三)LinkedList
前面学习了ArrayList的源码,数组是顺序存储结构,存储区间是连续的,占用内存严重,故空间复杂度很大.但数组的二分查找时间复杂度小,为O(1),数组的特点是寻址容易,插入和删除困难.今天学习另外的 ...
- 开源工具软件XMusicDownloader——音乐下载神器
XMusicDownloader,一款 支持从百度.网易.qq和酷狗等音乐网站搜索并下载歌曲的程序. 缘起: 一直用网易音乐听歌,但是诸如李健.周杰伦的不少歌曲,网易都没有版权,要从QQ等音乐去下载, ...
- python全栈开发day87~91-整个流程梳理、CRM功能、知识点梳理
1.流程 1. stark组件 1. 启动 2.注册 3.url设计 4.视图函数设计 1.展示数据头 2.展示数据 3.list_display功能实现 4.list_display_links 功 ...
- gcc make 与cmake
1. gcc (1)是什么? 它是GNU Compiler Collection(就是GNU编译器套件),也可以简单认为是编译器.它可以编译很多种编程语言(括C.C++.Objective-C.For ...
- yum安装的时候报错,关于python的函数库
我在执行yum -y install nc命令的时候出现如下报错 There was a problem importing one of the Python modulesrequired to ...
- Thinkphp3.1 php 链接SqlServer
ThinkPHP链接 M("lk_employeeInfo","Null/表前缀","sqlsrv://账号:密码@服务器:端口/数据库") ...