bzoj千题计划321:bzoj5251: [2018多省省队联测]劈配(网络流 + 二分)
https://www.lydsy.com/JudgeOnline/problem.php?id=5251
第一问:
左边一列点代表学生,右边一列点代表导师
导师向汇点连流量为 人数限制的 边
然后从第一个学生的第一志愿往里面加边
如果当前学生的当前志愿可以满足,即目前网络流可以满流,保留这一志愿的边,然后下一个学生
否则,删除这一志愿的边,然后下一个志愿
第二问:
二分这个学生要前进多少名
假设是学生i要前进x名
把前i-x-1名的学生 在第一问中满足的志愿 的边加进去
在把学生i的边加进去
判断是否满流
注意判断满流的时候 不包括前i-x-1名学生里没有任何导师的学生
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm> using namespace std; #define N 201
#define M 80801 int n,m; int lim[N];
int a[N][N][N];
int cnt[N][N]; int dream[N]; int tot=;
int src,decc;
int lev[N<<],cur[N<<];
int front[M<<],nxt[M<<],to[M<<],cap[M<<];
queue<int>q; int st[N]; inline void read(int &x)
{
x=; char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) { x=x*+c-''; c=getchar(); }
} inline void init()
{
read(n); read(m);
decc=n+m+;
for(int i=;i<=m;++i) read(lim[i]);
int x;
for(int i=;i<=n;++i)
for(int j=;j<=m;++j)
{
read(x);
if(x) a[i][x][++cnt[i][x]]=j;
}
for(int i=;i<=n;++i) read(dream[i]);
} inline void add(int u,int v,int w)
{
to[++tot]=v; nxt[tot]=front[u]; front[u]=tot; cap[tot]=w;
to[++tot]=u; nxt[tot]=front[v]; front[v]=tot; cap[tot]=;
} inline bool bfs()
{
for(int i=;i<=decc;++i) cur[i]=front[i],lev[i]=-;
while(!q.empty()) q.pop();
q.push(src);
lev[src]=;
int now,t;
while(!q.empty())
{
now=q.front();
q.pop();
for(int i=front[now];i;i=nxt[i])
{
t=to[i];
if(lev[t]==- && cap[i])
{
lev[t]=lev[now]+;
if(t==decc) return true;
q.push(t);
}
}
}
return false;
} inline int dinic(int now,int flow)
{
if(now==decc) return flow;
int rest=,delta;
for(int &i=cur[now];i;i=nxt[i])
if(cap[i] && lev[to[i]]==lev[now]+)
{
delta=dinic(to[i],min(flow-rest,cap[i]));
if(delta)
{
rest+=delta;
cap[i]-=delta; cap[i^]+=delta;
if(rest==flow) break;
}
}
if(rest!=flow) lev[now]=-;
return rest;
} void solve1()
{
for(int i=;i<=m;++i) add(n+i,decc,lim[i]);
int ok;
for(int i=;i<=n;++i)
{
add(src,i,);
for(int j=;j<=m;++j)
if(cnt[i][j])
{
for(int k=;k<=cnt[i][j];++k) add(i,n+a[i][j][k],);
if(bfs())
{
dinic(src,i);
st[i]=j;
break;
}
else
{
for(int k=,h=tot;k<=cnt[i][j];++k,h-=) cap[h]=cap[h-]=;
}
}
}
for(int i=;i<=n;++i) printf("%d ",st[i] ? st[i] : m+);
putchar('\n');
} inline bool check(int x,int goal)
{
tot=;
memset(front,,sizeof(front));
for(int i=;i<=m;++i) add(n+i,decc,lim[i]);
int ok=;
for(int i=;i<goal;++i)
{
add(src,i,);
if(!st[i])
{
ok++;
continue;
}
for(int j=;j<=cnt[i][st[i]];++j) add(i,n+a[i][st[i]][j],);
}
add(src,x,);
for(int i=;i<=dream[x];++i)
for(int j=;j<=cnt[x][i];++j) add(x,n+a[x][i][j],);
while(bfs()) ok+=dinic(src,goal);
return ok==goal;
} void solve2()
{
int l,r,mid,ans;
for(int i=;i<=n;++i)
{
if(st[i] && st[i]<=dream[i])
{
printf("0 ");
continue;
}
ans=i;
l=; r=i-;
while(l<=r)
{
mid=l+r>>;
if(check(i,i-mid)) ans=mid,r=mid-;
else l=mid+;
}
printf("%d ",ans);
}
putchar('\n');
} void clear()
{
memset(st,,sizeof(st));
memset(cnt,,sizeof(cnt));
memset(front,,sizeof(front));
tot=;
} int main()
{
//freopen("mentor.in","r",stdin);
//freopen("mentor.out","w",stdout);
int T,C;
read(T); read(C);
while(T--)
{
clear();
init();
solve1();
solve2();
}
}
bzoj千题计划321:bzoj5251: [2018多省省队联测]劈配(网络流 + 二分)的更多相关文章
- bzoj5251 [2018多省省队联测]劈配
直接网络流模拟即可AC. 可持久化+暴力=90分, 可持久化+二分=30分, 暴力加边+二分=100分. 我也很无奈啊. Ivan便涨红了脸,额上的青筋条条绽出,争辩道,“memcpy也是可持久化…… ...
- bzoj 5251: [2018多省省队联测]劈配
Description 一年一度的综艺节目<中国新代码>又开始了. Zayid从小就梦想成为一名程序员,他觉得这是一个展示自己的舞台,于是他毫不犹豫地报名了. 题目描述 轻车熟路的Zayi ...
- bzoj千题计划300:bzoj4823: [Cqoi2017]老C的方块
http://www.lydsy.com/JudgeOnline/problem.php?id=4823 讨厌的形状就是四联通图 且左右各连一个方块 那么破坏所有满足条件的四联通就好了 按上图方式染色 ...
- bzoj千题计划324:bzoj5249: [2018多省省队联测]IIIDX(线段树)
https://www.lydsy.com/JudgeOnline/problem.php?id=5249 把树建出来 如果所有的d互不相同,后续遍历即可 现在有的d相同 将d从小到大排序,考虑如何将 ...
- bzoj千题计划307:bzoj5248: [2018多省省队联测]一双木棋
https://www.lydsy.com/JudgeOnline/problem.php?id=5248 先手希望先手得分减后手得分最大,后手希望先手得分减后手得分最小 棋盘的局面一定是阶梯状,且从 ...
- bzoj千题计划196:bzoj4826: [Hnoi2017]影魔
http://www.lydsy.com/JudgeOnline/problem.php?id=4826 吐槽一下bzoj这道题的排版是真丑... 我还是粘洛谷的题面吧... 提供p1的攻击力:i,j ...
- bzoj千题计划177:bzoj1858: [Scoi2010]序列操作
http://www.lydsy.com/JudgeOnline/problem.php?id=1858 2018 自己写的第1题,一遍过 ^_^ 元旦快乐 #include<cstdio> ...
- bzoj千题计划280:bzoj4592: [Shoi2015]脑洞治疗仪
http://www.lydsy.com/JudgeOnline/problem.php?id=4592 注意操作1 先挖再补,就是补的范围可以包含挖的范围 SHOI2015 的题 略水啊(逃) #i ...
- bzoj千题计划317:bzoj4650: [Noi2016]优秀的拆分(后缀数组+差分)
https://www.lydsy.com/JudgeOnline/problem.php?id=4650 如果能够预处理出 suf[i] 以i结尾的形式为AA的子串个数 pre[i] 以i开头的形式 ...
随机推荐
- EMM386和UMBPCI 区别
EMM386和UMBPCI 区别 1,SupportCD-ROM[HIMEM+EMM386NOEMS].支持光驱(EMM386模式)2,SupportCD-ROM[HIMEM+UMBPCI].支持光驱 ...
- 使用Putty执行Rsync命令
背景介绍:公司的文件服务器有多个,一个Master服务器,10个左右的Slave服务器. 当Master服务器中的文件更新之后,Slave服务器中的文件也必须做相对应的同步操作. 公司目前使用的Rsy ...
- 「TJOI2015」概率论 解题报告
「TJOI2015」概率论 令\(f_i\)代表\(i\)个点树形态数量,\(g_i\)代表\(i\)个点叶子个数 然后列一个dp \[ f_i=\sum_{j=0}^{i-1} f_j f_{i-j ...
- cf245H Queries for Number of Palindromes (manacher+dp)
首先马拉车一遍(或者用hash),再做个前缀和处理出f[i][j]表示以j为右端点,左端点在[i,j]的回文串个数 然后设ans[i][j]是[i,j]之间的回文串个数,那就有ans[i][j]=an ...
- 自动驾驶技术之——无人驾驶中的CAN总线
CAN总线在整个无人驾驶系统中有着十分重要的作用.除了在VCU信号需要通过CAN总线进行传输外,无人车上的某些传感器(如雷达.Mobileye)的信号传递也是通过CAN实现的. 前言 本文主要内容是— ...
- 用go语言实现线程池
代码放在 https://github.com/bigben0123/workerPool 安装完go软件后.执行目录中的install.cmd即可.
- 逗号分隔的字符串与List互转
将逗号分隔的字符串转换为List // 将逗号分隔的字符串转换为List String str = "a,b,c"; // 1.使用JDK,逗号分隔的字符串-->数组--&g ...
- 洛谷P3959 宝藏
去年NOIP第二毒瘤(并不)的题终于被我攻克了,接下来就只剩noip难度巅峰列队了. 首先说一下三种做法:随机化,状压DP和搜索. 前两种做法我都A了,搜索实在是毒瘤,写鬼啊. 有些带DFS的记忆化搜 ...
- Nodejs nmp 常用命令
npm是一个node包管理和分发工具,已经成为了非官方的发布node模块(包)的标准.有了npm,可以很快的找到特定服务要使用的包,进行下载.安装以及管理已经安装的包. 1.npm install m ...
- MongoDB 学习记录(二)yum安装
前言:接着上篇继续学习MongoDB,这次学习的是在Linux下安装MongoDB 环境:centos7.3 安装版本:MongoDB4.0 官网安装教程地址 https://docs.mongodb ...