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开头的形式 ...
随机推荐
- Git Bash的妙用 - 使用Linux命令
如何在Windows中使用Linux命令? 网上有很多说是安装CygwinPortable 在cmd 窗口下是用linux 命令,但是还有一些缺陷. 其实对于程序员来说有一个非常简单有效的方法,那就是 ...
- 【 HDU2966 】In case of failure(KD-Tree)
BUPT2017 wintertraining(15) #5E HDU - 2966 题意 给平面直角坐标系下的n个点的坐标,求离每个点和它最近点的距离的平方.\(2 \le n \le 10^5\) ...
- TCP/IP 和 HTTP 的区别和联系是什么?
作者:车小胖链接:https://www.zhihu.com/question/38648948/answer/240006409来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注 ...
- 51NOD1174 区间最大数 && RMQ问题(ST算法)
RMQ问题(区间最值问题Range Minimum/Maximum Query) ST算法 RMQ(Range Minimum/Maximum Query),即区间最值查询,是指这样一个问题:对于长度 ...
- luogu3953 [NOIp2017]逛公园 (tarjan+dijkstra+记忆化搜索)
先跑一边dijkstra算出从1到i的最短距离dis[i] 然后建反向边 从n开始记忆化搜索,(p,k)表示1到p的距离=dis[p]+k的方案数 答案就是$\sum\limits_{i=0}^{k} ...
- hdu 1160 FatMouse's Speed (最长上升子序列+打印路径)
Problem Description FatMouse believes that the fatter a mouse is, the faster it runs. To disprove th ...
- css 选择符中的 >,+,~,=,^,$,*,|,:,空格 的意思
一,作为元素选择符 * 表示通配选择符 * {} // 所有元素 二,作为关系选择符 空格 表示包含选择符 a div{} // 被a元素包含的div > 表示子元素选择符 a > div ...
- QML学习笔记(三)-引入Font-awesome
作者: 狐狸家的鱼 Github: 八至 1.首先得在qml文件夹下建立字体文件,将font-awesome放入进去 2.然后在main.cpp中注册字体 引入中一定要写上 引用字体 引用字体得路径一 ...
- 快速傅里叶变换(FFT)
扯 去北京学习的时候才系统的学习了一下卷积,当时整理了这个笔记的大部分.后来就一直放着忘了写完.直到今天都腊月二十八了,才想起来还有个FFT的笔记没整完呢.整理完这个我就假装今年的任务全都over了吧 ...
- 苹果电脑python3安装pillow模块
我刚开始在苹果电脑自带的python 中安装了pillow模块,导致在后期我想在python3中安装pilow模块的时候 pip3 install pillow 但是总会提示错误说电脑中已经存在pil ...