luogu

我记得我第一次做这道题的时候屁都不会qwq

先考虑第一问,暴力是依次枚举每个人,然后从高到低枚举志愿,枚举导师,能选就选.但是可以发现前面的人选的导师可能会导致后面的人本来可以选到这个志愿,但是不能选.这个问题是不是有点眼熟?你可以理解成二分图匹配问题,就是对于每个人,枚举志愿,然后把这个志愿对应的一些导师连边,如果跑匹配能跑出来那么他就是这个志愿,否则撤销刚才的操作

第二问类似,暴力枚举某个人到了前面的哪一名,然后把前面其他人在第一问中的方案的图先建好,然后把对应志愿\(\le s_i\)的导师加入图,如果有那个人能匹配上那么就可以前进到这一名,还要记得撤销.做的时候可以先枚举后面的人到的名次,然后枚举人,这样前面的人的图可以快速建出来.每个人的答案是当前名次-最大的合法名次

实现用的是网络流,因为比较方便退流以及撤销边,开个栈栈序撤销.注意及时撤销

// luogu-judger-enable-o2
//qwqwq
#include<bits/stdc++.h>
#define LL long long
#define uLL unsigned long long
#define db double using namespace std;
const int N=200+10,M=3e5+10;
const db eps=1e-4;
int rd()
{
int x=0,w=1;char ch=0;
while(ch<'0'||ch>'9'){if(ch=='-') w=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
return x*w;
}
int to[M],nt[M],c[M],hd[N<<1],tot=1;
void add(int x,int y,int z)
{
++tot,to[tot]=y,nt[tot]=hd[x],c[tot]=z,hd[x]=tot;
++tot,to[tot]=x,nt[tot]=hd[y],c[tot]=0,hd[y]=tot;
}
void wd(){hd[to[tot^1]]=nt[tot],--tot;}
int stk[M<<3][2],tp;
void wdflow()
{
while(tp)
{
int i=stk[tp][0],dt=stk[tp][1];
c[i]+=dt,c[i^1]-=dt;
--tp;
}
}
int ps,pt,lv[N<<1];
queue<int> q;
bool bfs()
{
for(int i=0;i<=pt;++i) lv[i]=0;
lv[ps]=1,q.push(ps);
while(!q.empty())
{
int x=q.front();
q.pop();
for(int i=hd[x];i;i=nt[i])
{
int y=to[i];
if(c[i]>0&&!lv[y])
{
lv[y]=lv[x]+1;
q.push(y);
}
}
}
return lv[pt];
}
int dfs(int x,int fw)
{
if(x==pt) return fw;
int an=0;
for(int i=hd[x];i;i=nt[i])
{
int y=to[i];
if(c[i]>0&&lv[y]==lv[x]+1)
{
int dt=dfs(y,min(fw,c[i]));
stk[++tp][0]=i,stk[tp][1]=dt;
c[i]-=dt,c[i^1]+=dt;
fw-=dt,an+=dt;
if(!fw) break;
}
}
return an;
}
int dinic()
{
int an=0,dt;
while(bfs())
while((dt=dfs(ps,2333333)))
an+=dt;
return an;
}
int n,m,an[N],a2[N],b[N],s[N];
vector<int> dls[N][N];
vector<int>::iterator it; int main()
{
int T=rd();
rd();
while(T--)
{
n=rd(),m=rd();
ps=0,pt=n+m+1;
for(int i=0;i<=pt;++i) hd[i]=0;
tot=1;
for(int i=1;i<=n;++i)
{
add(ps,i+m,1);
for(int j=1;j<=m+1;++j) dls[i][j].clear();
}
for(int i=1;i<=m;++i) add(i,pt,b[i]=rd());
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)
dls[i][rd()].push_back(j);
for(int i=1;i<=n;++i)
{
an[i]=m+1;
for(int j=1;j<=m;++j)
{
if(!dls[i][j].size()) continue;
int latt=tot;
for(it=dls[i][j].begin();it!=dls[i][j].end();++it)
add(i+m,*it,1);
tp=0;
if(dinic()){an[i]=j;break;}
wdflow();
while(tot>latt) wd();
}
printf("%d ",an[i]);
}
puts("");
for(int i=1;i<=n;++i) s[i]=rd();
for(int i=0;i<=pt;++i) hd[i]=0;
tot=1;
for(int i=1;i<=n;++i) add(ps,i+m,1),a2[i]=0;
for(int i=1;i<=m;++i) add(i,pt,b[i]);
for(int i=1;i<=n;++i)
{
for(int j=i;j<=n;++j)
{
if(an[j]<=s[j]){a2[j]=j;continue;}
int latt=tot;
for(int k=1;k<=s[j];++k)
{
if(!dls[j][k].size()) continue;
for(it=dls[j][k].begin();it!=dls[j][k].end();++it)
add(j+m,*it,1);
}
tp=0;
if(dinic()) a2[j]=i;
wdflow();
while(tot>latt) wd();
}
for(it=dls[i][an[i]].begin();it!=dls[i][an[i]].end();++it)
add(i+m,*it,1);
tp=0,dinic();
}
for(int i=1;i<=n;++i) printf("%d ",i-a2[i]);
puts("");
}
return 0;
}

luogu P4382 [九省联考2018]劈配的更多相关文章

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

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

  2. BZOJ5251:[九省联考2018]劈配——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=5251 https://loj.ac/problem/2477  <-可以看数据 https: ...

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

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

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

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

  5. [luogu] P4364 [九省联考2018]IIIDX(贪心)

    P4364 [九省联考2018]IIIDX 题目背景 Osu 听过没?那是Konano 最喜欢的一款音乐游戏,而他的梦想就是有一天自己也能做个独特酷炫的音乐游戏.现在,他在世界知名游戏公司KONMAI ...

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

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

  7. luogu P4365 [九省联考2018]秘密袭击coat

    luogu 这里不妨考虑每个点的贡献,即求出每个点在多少个联通块中为第\(k\)大的(这里权值相同的可以按任意顺序排大小),然后答案为所有点权值\(*\)上面求的东西之和 把比这个点大的点看成\(1\ ...

  8. luogu P4363 [九省联考2018]一双木棋chess

    传送门 对抗搜索都不会,我真是菜死了qwq 首先根据题目条件,可以发现从上到下每一行的棋子数是单调不增的,然后n m都比较小,如果把状态搜出来,可以发现合法状态并不多,所以可以用一个11进制数表示状态 ...

  9. 【题解】Luogu P4363 [九省联考2018]一双木棋chess

    原题传送门 这道题珂以轮廓线dp解决 经过推导,我们珂以发现下一行的棋子比上一行的棋子少(或等于),而且每一行中的棋子都是从左向右依次排列(从头开始,中间没有空隙) 所以每下完一步棋,棋盘的一部分是有 ...

随机推荐

  1. [JZOJ5398]:Adore(状压DP+记忆化搜索)

    题目描述 小$w$偶然间见到了一个$DAG$. 这个$DAG$有$m$层,第一层只有一个源点,最后一层只有一个汇点,剩下的每一层都有$k$个节点. 现在小$w$每次可以取反第$i(1<i< ...

  2. 分布式-信息方式-ActiveMQ的消息存储持久化

    ActiveMQ的消息存储持久化■概述ActiveMQ不仅支持 persistent和 non-persistent两种方式,还支持消息的恢复( recovery)方式PTPQueue的存储是很简单的 ...

  3. kotlin实现流读取

    在Java对流的读取是下面的那样,当前不要忘记流的关闭close. // java 代码void someFunc(InputStream in, OutputStream out) throws I ...

  4. MongoDB中的_id和ObjectId

    ObjectId是"_id"的默认类型.它设计成轻量型的,不同的机器都能用全局唯一的同种方法方便地生成它. 这是MongoDB采用ObjectId,而不是其他比较常规的做法(比如自 ...

  5. 【Spark机器学习速成宝典】模型篇02逻辑斯谛回归【Logistic回归】(Python版)

    目录 Logistic回归原理 Logistic回归代码(Spark Python) Logistic回归原理 详见博文:http://www.cnblogs.com/itmorn/p/7890468 ...

  6. leecode 238除自身以外数组的乘积

    class Solution { public: vector<int> productExceptSelf(vector<int>& nums) { //用除法必须要 ...

  7. 启用 SR-IOV 解决 Neutron 网络 I/O 性能瓶颈

    目录 文章目录 目录 前言 Neutron 的网络实现模型 基于虚拟网络设备的虚拟机流量走向 Neutron 网络实现模型的性能瓶颈 SR-IOV 技术简介 在 Neutron 中引入 SR-IOV ...

  8. 阶段3 2.Spring_10.Spring中事务控制_5 spring事务控制的代码准备

    创建一个工程,只搭建环境不做配置.等配置的时候把这个项目相关的代码再复制到新项目里面 jar包的打包方式 导入包 事务控制也是基于AOP的.所以这里导入aspectjweaver 复制jdbcTemp ...

  9. Elasticsearch 6.2.3版本 同一个index新增type报错 Rejecting mapping update to [website] as the final mapping would have more than 1 type: [blog2, blog]

    在website的index下已经存在一个名为blog的type.想在website下,新增一个名为blog2的type. 执行语句如下: PUT /website/blog2/1 { "t ...

  10. 浏览器从输入URL到渲染出页面发生了什么

    总体来说分为以下几个过程: 1.  DNS解析 2. TCP连接 3. 发送HTTP请求 4. 服务器处理请求并返回HTTP报文 5. 浏览器解析渲染页面 6. 连接结束 参考资料:[https:// ...