BZOJ5251 八省联考2018劈配(网络流)
劈配,匹配,网络流。那么考虑怎么跑网络流。
先看第一问。首先套路的建出超源超汇。不用想也知道导师向汇连容量为战队人数上限的边。特别地,给出局也建一个点,向汇连容量inf的边(似乎没有必要)。对于一个新学员,假设我们已经知道了之前的学员的最优选择,可以把之前的每名学员和可以选择的导师连边,并由源向学员连容量为1的边。然后对于该名新学员,先只连最优选择的边,如果此时跑出的最大流不等于学员数,则表明这名学员无法选择最优,那么删掉最优边(此时这些边里一定没有流量,可以通过容量改为0实现)并连上次优边,次优边还是不行的话继续,一直这样下去直到最大流等于学员数。第一问就做完了。至于复杂度,O(能过)。
然后是第二问。对于每个人可以二分答案,然后跑最大流看其是否满足。似乎需要访问网络的历史状态?可持久化网络流!这玩意似乎没法可持久化啊……那就暴力记下来呗。由于有C的限制,这里面的边不会很多。于是就做完了,O(能过)。还有一种做法是先连上该学员可以选择的边,然后从第一名开始依次把最优选择加进去跑,直到无法满足,可能会快不少。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
#define N 210
#define S 0
#define T 404
int test,c,n,m,b[N],s[N],p[N<<],cnt[N],t;
int cur[N<<],d[N<<],q[N<<],ans,cho[N];
vector<int> a[N][N];
struct data{int to,nxt,cap,flow;
}edge[N*N<<],hisedge[N][];
void addedge(int x,int y,int z)
{
t++;edge[t].to=y,edge[t].nxt=p[x],edge[t].cap=z,edge[t].flow=,p[x]=t;
t++;edge[t].to=x,edge[t].nxt=p[y],edge[t].cap=,edge[t].flow=,p[y]=t;
}
void addedge(int x,int y,int cap,int flow)
{
t++;edge[t].to=y,edge[t].nxt=p[x],edge[t].cap=cap,edge[t].flow=flow,p[x]=t;
t++;edge[t].to=x,edge[t].nxt=p[y],edge[t].cap=,edge[t].flow=-flow,p[y]=t;
}
void init()
{
for (int i=;i<=m;i++) b[i]=read();
for (int i=;i<=n;i++)
{
for (int j=;j<=m+;j++)
a[i][j].clear();
for (int j=;j<=m;j++)
{
int x=read();
if (x) a[i][x].push_back(j);
}
a[i][m+].push_back(m+);
}
for (int i=;i<=n;i++) s[i]=read();
}
bool bfs()
{
memset(d,,sizeof(d));d[S]=;
int head=,tail=;q[]=S;
do
{
int x=q[++head];
for (int i=p[x];~i;i=edge[i].nxt)
if (d[edge[i].to]==-&&edge[i].flow<edge[i].cap)
{
d[edge[i].to]=d[x]+;
q[++tail]=edge[i].to;
}
}while (head<tail);
return ~d[T];
}
int work(int k,int f)
{
if (k==T) return f;
int used=;
for (int i=cur[k];~i;i=edge[i].nxt)
if (d[k]+==d[edge[i].to])
{
int w=work(edge[i].to,min(f-used,edge[i].cap-edge[i].flow));
edge[i].flow+=w,edge[i^].flow-=w;
if (edge[i].flow<edge[i].cap) cur[k]=i;
used+=w;if (used==f) return f;
}
if (used==) d[k]=-;
return used;
}
void dinic()
{
while (bfs())
{
memcpy(cur,p,sizeof(p));
ans+=work(S,N);
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("bzoj5251.in","r",stdin);
freopen("bzoj5251.out","w",stdout);
const char LL[]="%I64d";
#else
const char LL[]="%lld";
#endif
test=read(),c=read();
while (test--)
{
n=read(),m=read();
t=-;
memset(p,,sizeof(p));
memset(cnt,,sizeof(cnt));
init();
for (int i=;i<=m;i++) addedge(n+i,T,b[i]);
addedge(n+m+,T,N);
for (int j=;j<=t;j+=)
if (edge[j].cap) hisedge[][++cnt[]]=edge[j],hisedge[][cnt[]].nxt=edge[j^].to;
ans=;
for (int i=;i<=n;i++)
{
addedge(S,i,);
for (int j=;j<=m+;j++)
{
int tmp=t;
for (int k=;k<a[i][j].size();k++)
addedge(i,n+a[i][j][k],);
dinic();
if (ans==i) {cho[i]=j;break;}
for (int k=tmp+;k<=t;k+=) edge[k].cap=;
}
for (int j=;j<=t;j+=)
if (edge[j].cap) hisedge[i][++cnt[i]]=edge[j],hisedge[i][cnt[i]].nxt=edge[j^].to;
}
/*for (int i=0;i<=n;i++)
{
for (int j=1;j<=cnt[i];j++)
cout<<hisedge[i][j].nxt<<' '<<hisedge[i][j].to<<' '<<hisedge[i][j].cap<<' '<<hisedge[i][j].flow<<endl;
cout<<endl;
}*/
for (int i=;i<=n;i++) printf("%d ",cho[i]);
cout<<endl;
for (int i=;i<=n;i++)
{
int l=,r=i-,add=-;
while (l<=r)
{
int mid=l+r>>;
memset(p,,sizeof(p));
t=-;
addedge(S,i,);
for (int j=;j<=s[i];j++)
for (int k=;k<a[i][j].size();k++)
addedge(i,n+a[i][j][k],);
for (int j=;j<=cnt[mid];j++)
addedge(hisedge[mid][j].nxt,hisedge[mid][j].to,hisedge[mid][j].cap,hisedge[mid][j].flow);
ans=;
dinic();
if (!ans) r=mid-;
else l=mid+,add=mid;
}
printf("%d ",i-add-);
}
cout<<endl;
}
return ;
}
BZOJ5251 八省联考2018劈配(网络流)的更多相关文章
- [BZOJ5251][九省联考2018]劈配(网络流)
5251: [2018多省省队联测]劈配 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 33 Solved: 22[Submit][Status][ ...
- [八省联考2018] 劈配 mentor
Description 一年一度的综艺节目<中国新代码>又开始了.Zayid 从小就梦想成为一名程序员,他觉得这是一个展示自己的舞台,于是他毫不犹豫地报名了. Input 轻车熟路的Zay ...
- BZOJ.5251.[八省联考2018]劈配mentor(最大流)
BZOJ 洛谷 对于每个人,每次枚举一个志愿看是否能增广即可. 对于第二问,可以保留第一问中\(n\)次增广前后的\(n\)张图,二分,在对应图上看是否能增广即可. 貌似匈牙利的某种写法比网络流优多了 ...
- 洛谷P4382 [八省联考2018]劈配(网络流,二分答案)
洛谷题目传送门 说不定比官方sol里的某理论最优算法还优秀一点? 所以\(n,m\)说不定可以出到\(1000\)? 无所谓啦,反正是个得分题.Orz良心出题人,暴力有70分2333 思路分析 正解的 ...
- P4382 [八省联考2018]劈配
题目链接 题意分析 受到了\(olinr\ \ julao\)的影响 写了匈牙利算法 首先 我们对于每一个人 从高到低枚举志愿 如果当前志愿的老师有剩余的话 那么我们就选 否则的话 我们看看谁的那个志 ...
- BZOJ5251:[九省联考2018]劈配——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=5251 https://loj.ac/problem/2477 <-可以看数据 https: ...
- luogu P4382 [九省联考2018]劈配
luogu 我记得我第一次做这道题的时候屁都不会qwq 先考虑第一问,暴力是依次枚举每个人,然后从高到低枚举志愿,枚举导师,能选就选.但是可以发现前面的人选的导师可能会导致后面的人本来可以选到这个志愿 ...
- 【BZOJ5251】【八省联考2018】劈配(网络流,二分答案)
[BZOJ5251][八省联考2018]劈配(网络流,二分答案) 题面 洛谷 BZOJ Description 一年一度的综艺节目<中国新代码>又开始了. Zayid从小就梦想成为一名程序 ...
- [八省联考2018]林克卡特树lct——WQS二分
[八省联考2018]林克卡特树lct 一看这种题就不是lct... 除了直径好拿分,别的都难做. 所以必须转化 突破口在于:连“0”边 对于k=0,我们求直径 k=1,对于(p,q)一定是从p出发,走 ...
随机推荐
- Sublime3 - 插件cssrem
一个CSS的px值转rem值的Sublime Text 3自动完成插件. 插件效果如下: 安装: 1. 现在本地clone一份: git clone https://github.com/hyb628 ...
- 没有内涵段子可以刷了,利用Python爬取段友之家贴吧图片和小视频(含源码)
由于最新的视频整顿风波,内涵段子APP被迫关闭,广大段友无家可归,但是最近发现了一个"段友"的app,版本更新也挺快,正在号召广大段友回家,如下图,有兴趣的可以下载看看(ps:我不 ...
- CF1110H Modest Substrings AC自动机、DP
传送门 如果\(r-l\)比较小,可以将所有满足条件的串扔进\(AC\)自动机然后在上面DP,从前往后确定字符串的每一位. 但是\(l,r \leq 10^{800}\)就十分不可行,所以需要优化这个 ...
- CF1039E Summer Oenothera Exhibition 贪心、根号分治、倍增、ST表
传送门 感谢这一篇博客的指导(Orzwxh) $PS$:默认数组下标为$1$到$N$ 首先很明显的贪心:每一次都选择尽可能长的区间 不妨设$d_i$表示在取当前$K$的情况下,左端点为$i$的所有满足 ...
- 2-SAT超入门讲解
Preface 说实话2-SAT的题目我都没怎么做过,所以这里讲的都是些超入门什么的 还有一些板子题,由于是暑假的时候学的所以有些我也记不清了 主要学习参考自:Mancher的课件&& ...
- JXOI2018简要题解
JXOI2018简要题解 T1 排序问题 题意 九条可怜是一个热爱思考的女孩子. 九条可怜最近正在研究各种排序的性质,她发现了一种很有趣的排序方法: Gobo sort ! Gobo sort 的算法 ...
- BJOI2018简要题解
BJOI2018简要题解 D1T1 二进制 题意 pupil 发现对于一个十进制数,无论怎么将其的数字重新排列,均不影响其是不是 \(3\) 的倍数.他想研究对于二进制,是否也有类似的性质. 于是他生 ...
- 【强化学习】python 实现 q-learning 例四(例二改写)
将例二改写成面向对象模式,并加了环境! 不过更新环境的过程中,用到了清屏命令,play()的时候,会有点问题.learn()的时候可以勉强看到:P 0.效果图 1.完整代码 相对于例一,修改的地方: ...
- 【精】【入门篇】js正则表达式
前言 最近有了点时间,就回头看了一下<学习正则表达式>这本书.怎么说呢,这本书适合从零开始学习正则表达式或者有一点基础但是想要加强这方面能力的读者.这本书的风格是“实践出真知”,使用归纳方 ...
- Net-SNMP V3协议 安装配置笔记(CentOS 6.3/5.6)
注意:snmp V3,需要需要关闭selinux和防火墙: 关闭selinux方法: #vi /etc/selinux/config 将文件中的SELINUX="" 为 disab ...