Description

Link.

一年一度的综艺节目《中国新代码》又开始了。Zayid 从小就梦想成为一名程序员,他觉得这是一个展示自己的舞台,于是他毫不犹豫地报名了。

轻车熟路的 Zayid 顺利地通过了海选,接下来的环节是导师盲选,这一阶段的规则是这样的:

总共 \(n\) 名参赛选手(编号从 \(1\) 至 \(n\))每人写出一份代码并介绍自己的梦想。接着由所有导师对这些选手进行排名。为了避免后续的麻烦,规定不存在排名并列的情况。

同时,每名选手都将独立地填写一份志愿表,来对总共 \(m\) 位导师(编号从 \(1\) 至 \(m\))作出评价。志愿表上包含了共 \(m\) 档志愿。对于每一档志愿,选手被允许填写最多 \(C\) 位导师,每位导师最多被每位选手填写一次(放弃某些导师也是被允许的)。

在双方的工作都完成后,进行录取工作。每位导师都有自己战队的人数上限,这意味着可能有部分选手的较高志愿、甚至是全部志愿无法得到满足。

节目组对 ‘‘前 \(i\) 名的录取结果最优’’ 作出如下定义:

  • 前 \(1\) 名的录取结果最优,当且仅当第 \(1\) 名被其最高非空志愿录取(特别地,如果第 \(1\) 名没有填写志愿表,那么该选手出局)。
  • 前 \(i\) 名的录取结果最优,当且仅当在前 \(i − 1\) 名的录取结果最优的情况下:第 \(i\) 名被其理论可能的最高志愿录取(特别地,如果第 \(i\) 名没有填写志愿表、或其所有志愿中的导师战队均已员,那么该选手出局)。

如果一种方案满足 ‘‘前 \(n\) 名的录取结果最优’’,那么我们可以简称这种方案是最优的。

举例而言,\(2\) 位导师 T 老师、F 老师的战队人数上限分别都是 \(1\) 人;\(2\) 位选手 Zayid、DuckD 分列第 \(1\)、\(2\) 名。那么下面 \(3\) 种志愿表及其对应的最优录取结果如表中所示:

选手 第 \(1\) 志愿 第 \(2\) 志愿 录取志愿 加入战队
Zayid N/A T 老师、F 老师 2 F 老师
DuckD T 老师 F 老师 1 T 老师
选手 第 \(1\) 志愿 第 \(2\) 志愿 录取志愿 加入战队
Zayid T 老师 F 老师 1 T 老师
DuckD T 老师 F 老师 2 F 老师
选手 第 \(1\) 志愿 第 \(2\) 志愿 录取志愿 加入战队
Zayid F 老师 N/A 1 F 老师
DuckD F 老师 N/A 出局 N/A

可以证明,对于上面的志愿表,对应的方案都是唯一的最优录取结果。

每个人都有一个自己的理想值 \(s_i\),表示第 \(i\) 位同学希望自己被第 \(s_i\) 或更高的志愿录

取,如果没有,那么他就会非常沮丧。

现在,所有选手的志愿表和排名都已公示。巧合的是,每位选手的排名都恰好与它

们的编号相同。

对于每一位选手,Zayid 都想知道下面两个问题的答案:

  • 在最优的录取方案中,他会被第几志愿录取。
  • 在其他选手相对排名不变的情况下,至少上升多少名才能使得他不沮丧。

    作为《中国新代码》的实力派代码手,Zayid 当然轻松地解决了这个问题。不过他

    还是想请你再算一遍,来检验自己计算的正确性。

你可能注意到了根本没有概括因为太 tm 长了妈妈我不想概括

Solution

这份题面真难读。

对于第一问,网络流;

我们把学生和导师分别放到左右两列弄成一个二分图.

源点连容量为 \(1\) 的学生边,然后让第一个学生连第一志愿,容量为 \(1\),如果能流量有增就下一个,否则删除这条边下一个;

导师往汇点连人数限制的边。

对于第二问,同样网络流。

每个学生二分其最终排名,若学生 \(x\) 的最终排名为 \(k\),就用第一问的条件把 \(x-k-1\) 名学生的边连上看是否满流。

#include<bits/stdc++.h>
const int INF=1e9;
std::queue<int> q;
std::vector<int> a[210][210];
int n,m,head[90010],nxt[180010],to[180010],cap[180010],Cur[900010],dep[900010],src,snk,cntot=1,up[210],s[210],ans[210];
void addEdge(int one,int ano,int val)
{
to[++cntot]=ano;
cap[cntot]=val;
nxt[cntot]=head[one];
head[one]=cntot; to[++cntot]=one;
cap[cntot]=0;
nxt[cntot]=head[ano];
head[ano]=cntot;
}
bool MF_bfs()
{
for(int i=1;i<=n+m+2;++i)
{
Cur[i]=head[i];
dep[i]=INF;
}
q.push(src);
dep[src]=1;
while(!q.empty())
{
int now=q.front();
q.pop();
for(int i=head[now];i;i=nxt[i])
{
int y=to[i];
if(cap[i] && dep[y]==INF)
{
dep[y]=dep[now]+1;
q.push(y);
}
}
}
return dep[snk]^INF;
}
int MF_dfs(int x,int in)
{
if(x==snk) return in;
else
{
int out=0;
for(int &i=Cur[x];i;i=nxt[i])
{
int y=to[i];
if(cap[i] && dep[y]==dep[x]+1)
{
int tmp=MF_dfs(y,std::min(in,cap[i]));
cap[i]-=tmp;
cap[i^1]+=tmp;
in-=tmp;
out+=tmp;
if(!in) break;
}
}
if(!out) dep[x]=INF;
return out;
}
}
int Dinic()
{
int res=0;
while(MF_bfs()) res+=MF_dfs(src,INF);
return res;
}
bool check(int x,int all)
{
cntot=1;
for(int i=1;i<=n+m+2;++i) head[i]=0;
addEdge(src,x,1);
for(int i=1;i<=m;++i) addEdge(n+i,snk,up[i]);
int low=0;
for(int i=1;i<all;++i)
{
addEdge(src,i,1);
if(ans[i])
{
for(int now:a[i][ans[i]]) addEdge(i,n+now,1);
}
else ++low;
}
for(int i=1;i<=s[x];++i)
{
for(int now:a[x][i]) addEdge(x,now+n,1);
}
return low+Dinic()==all;
}
int search(int l,int r)
{
int res=r+1,ID=r+1;
while(l<=r)
{
int mid=(l+r)>>1;
if(check(ID,ID-mid))
{
res=mid;
r=mid-1;
}
else l=mid+1;
}
return res;
}
void Go()
{
scanf("%d %d",&n,&m);
for(int i=1;i<=m;++i) scanf("%d",&up[i]);
for(int i=1;i<=n;++i)
{
for(int j=1,x;j<=m;++j)
{
scanf("%d",&x);
if(x) a[i][x].emplace_back(j);
}
}
for(int i=1;i<=n;++i) scanf("%d",&s[i]); src=n+m+1;
snk=n+m+2;
for(int i=1;i<=m;++i) addEdge(n+i,snk,up[i]);
for(int i=1;i<=n;++i)
{
addEdge(src,i,1);
for(int j=1;j<=m;++j)
{
if(!a[i][j].empty())
{
for(int now:a[i][j]) addEdge(i,now+n,1);
if(MF_bfs())
{
int waste=MF_dfs(src,INF);
ans[i]=j;
break;
}
else
{
int cur=cntot;
for(int k=1;k<=int(a[i][j].size());++k)
{
cap[cur]=cap[cur^1]=0;
cur-=2;
}
}
}
}
} for(int i=1;i<=n;++i)
{
if(ans[i]) printf("%d ",ans[i]);
else printf("%d ",m+1);
}
printf("\n"); for(int i=1;i<=n;++i)
{
if(ans[i] && ans[i]<=s[i]) printf("0 ");
else printf("%d ",search(1,i-1));
}
printf("\n"); for(int i=1;i<=n+m+2;++i) head[i]=0;
for(int i=1;i<=n;++i) ans[i]=0;
for(int i=1;i<=n;++i)
{
for(int j=1;j<=m;++j) a[i][j].clear();
}
cntot=1;
}
int main()
{
int T,waste;
scanf("%d %d",&T,&waste);
while(T-->0) Go();
return 0;
}

Solution -「九省联考 2018」劈配的更多相关文章

  1. 「九省联考 2018」IIIDX 解题报告

    「九省联考 2018」IIIDX 这什么鬼题,送的55分要拿稳,实测有60? 考虑把数值从大到小摆好,每个位置\(i\)维护一个\(f_i\),表示\(i\)左边比它大的(包括自己)还有几个数可以选 ...

  2. LOJ #2473. 「九省联考 2018」秘密袭击

    #2473. 「九省联考 2018」秘密袭击 链接 分析: 首先枚举一个权值W,计算这个多少个连通块中,第k大的数是这个权值. $f[i][j]$表示到第i个节点,有j个大于W数的连通块的个数.然后背 ...

  3. Loj #2479. 「九省联考 2018」制胡窜

    Loj #2479. 「九省联考 2018」制胡窜 题目描述 对于一个字符串 \(S\),我们定义 \(|S|\) 表示 \(S\) 的长度. 接着,我们定义 \(S_i\) 表示 \(S\) 中第 ...

  4. LOJ 2743(洛谷 4365) 「九省联考 2018」秘密袭击——整体DP+插值思想

    题目:https://loj.ac/problem/2473 https://www.luogu.org/problemnew/show/P4365 参考:https://blog.csdn.net/ ...

  5. [loj 2478][luogu P4843]「九省联考 2018」林克卡特树

    传送门 Description 小L 最近沉迷于塞尔达传说:荒野之息(The Legend of Zelda: Breath of The Wild)无法自拔,他尤其喜欢游戏中的迷你挑战. 游戏中有一 ...

  6. @loj - 2478@「九省联考 2018」林克卡特树

    目录 @description@ @solution@ @part - 1@ @part - 2@ @accepted code@ @details@ @description@ 小 L 最近沉迷于塞 ...

  7. 【LOJ】#2479. 「九省联考 2018」制胡窜

    题解 老了,国赛之前敲一个后缀树上LCT和线段树都休闲的很 现在后缀树上线段树合并差点把我写死 主要思路就是后缀树+线段树合并+容斥,我相信熟练的OIer看到这已经会了 但就是不想写 但是由于我过于老 ...

  8. LOJ#2471「九省联考 2018」一双木棋 MinMax博弈+记搜

    题面 戳这里 题解 因为每行取的数的个数是单调不增的,感觉状态数不会很多? 怒而记搜,结果过了... #include<bits/stdc++.h> #define For(i,x,y) ...

  9. loj2472 「九省联考 2018」IIIDX

    ref #include <algorithm> #include <iostream> #include <cstdio> using namespace std ...

  10. 【BZOJ5251】【八省联考2018】劈配(网络流,二分答案)

    [BZOJ5251][八省联考2018]劈配(网络流,二分答案) 题面 洛谷 BZOJ Description 一年一度的综艺节目<中国新代码>又开始了. Zayid从小就梦想成为一名程序 ...

随机推荐

  1. 解决MySQL自动弹出命令行窗口

    自从装了MySQL之后,我的电脑就会在某些时刻弹出一个黑乎乎的命令行窗口,然后立马消失.一开始还以为是电脑出了什么故障,但一直没有出现其他什么问题,就是玩游戏时弹出来有点难受.有一次我眼睛看到了一闪而 ...

  2. .NET7 for LoongArch64(国产龙芯)

    目前龙芯通过自己的指令集LA64支持了.Net7.0.1版本,一同被支持的有Ruby,Nodejs,Java,Electron,Python等.原文:在此处 龙芯.Net7 sdk下载地址: http ...

  3. instance norm

    与Batch Norm加快计算收敛不同, IN是在[1]中提出的,目的是提高style transfer的表现. 计算如下: \[IN(x)=\gamma (\frac{x-\mu(x)}{\sigm ...

  4. Apache Hudi 元数据字段揭秘

    介绍 Apache Hudi 最初由Uber于 2016 年开发,旨在实现一个交易型数据湖,该数据湖可以快速可靠地支持更新,以支持公司拼车平台的大规模增长. Apache Hudi 现在被业内许多人广 ...

  5. 阿里云 MongoDB 创建库添加用户并授权

    先通过 root 进到 admin 库, 右击test 选择用户管理 测试连接

  6. flutter小白是如何在一周内用chatGPT开发一款App的

    创作初衷 这篇文章创作的初衷,只是为了写一个有关日历类的软件供自己使用,考虑到自己从来还没有使用flutter正式创作一个app,因此磨刀霍霍想试一试. 至于为什么要做一款日历软件,因为发现市面上的关 ...

  7. ERP导出(自定义格式表格)R报表开发代码

    按照正常流程新建程序,画面修改上传,程序下载修改 导入JAVA包,在global.import下 IMPORT com IMPORT JAVA java.net.URL IMPORT JAVA org ...

  8. Python copy & deeocopy 探究

    简单来说,copy 复制创建新的容器,而引用容器内元素的地址不变.而 deepcopy 也对容器内的容器元素进行复制. 但是这种复制具体是什么体现呢?是否只是对第一层容器元素进行了复制?写了一段代码验 ...

  9. Python根目录中没有Scripts文件夹问题

    电脑版本是win10,配置好python的环境变量,确保可以运行python命令. 1.打开cmd命令行输入 python -m ensurepip 2.查看Python根目录下,有没有新生成Scri ...

  10. subprocess Python执行系统命令最优选模块

    简介 subprocess 是 Python 中执行操作系统级别的命令的模块,所谓系级级别的命令就是如ls /etc/user ifconfig 等和操作系统有关的命令. subprocess 创建子 ...