洛谷P4382 劈配
不知道这个Zayid是谁...
题意:
有n个人,m个导师。每个导师能接纳bi个人,每个人对于这m个导师都有一个志愿档次。
优先满足靠前的人,问到最后每个人匹配的导师是他的第几志愿。
每个人又有一个限制si,问至少前进多少名才能被志愿档次不大于si的导师录取。
解:
首先发现,每个志愿档次只能填一个人的时候,可以直接贪心。否则在同一志愿档次内选择不同的导师会对后面有影响。
这时我们就可以利用网络流。
一个流量代表一个的归属,动态加边。
对于每个人枚举志愿档次,添加流向导师的边。然后看是否有流量。
如果有流量那么他就归于该志愿档次。
第二问,答案可以二分。
很简朴的想法是对于每个二分出来的值,重新建图来一遍。这样复杂度就是Tnlogn * nm,显然不行。
发现每次重新建图的时候我们进行了很多一模一样的操作。于是考虑把前k个人的网络流状态保存下来,之后直接调用。
但是太麻烦了...我们又发现一种很巧妙的方法:判断在前k个人加完之后是否可行,其实是看哪些导师还可以接纳人。于是我们从汇点出发,反向DFS,能够得到每次从哪些导师出发有增广路,就是哪些导师还能接纳。
然后二分的时候直接O(m)判定。
这样我们发现有90分,超时一个点。
回想第一问网络流的时候,如果一个志愿档次没有流量,那么这些加的边就没有用,不妨删了。
然后就A了...
1 #include <queue> 2 #include <cstdio> 3 #include <vector> 4 #include <cstring> 5 #include <algorithm> 6 7 const int N = 210, INF = 0x3f3f3f3f; 8 9 int b[N], C, n, m, a[N][N], s[N], mat[N]; 10 std::vector<int> topo[N][N]; 11 12 namespace fl { 13 14 struct Edge { 15 int nex, v, c; 16 }edge[2000010]; int top = 1; 17 18 int d[N << 1], e[N << 1], E[N << 1], TOP; 19 bool vis[N][N << 1]; 20 std::queue<int> Q; 21 22 inline void add(int x, int y, int z) { 23 top++; 24 edge[top].v = y; 25 edge[top].c = z; 26 edge[top].nex = e[x]; 27 e[x] = top; 28 29 top++; 30 edge[top].v = x; 31 edge[top].c = 0; 32 edge[top].nex = e[y]; 33 e[y] = top; 34 return; 35 } 36 37 inline bool BFS(int s, int t) { 38 memset(d, 0, sizeof(d)); 39 d[s] = 1; 40 Q.push(s); 41 while(!Q.empty()) { 42 int x = Q.front(); 43 Q.pop(); 44 for(int i = e[x]; i; i = edge[i].nex) { 45 int y = edge[i].v; 46 if(!edge[i].c || d[y]) { 47 continue; 48 } 49 d[y] = d[x] + 1; 50 Q.push(y); 51 } 52 } 53 return d[t]; 54 } 55 56 int DFS(int x, int t, int maxF) { 57 if(x == t) { 58 return maxF; 59 } 60 int Ans = 0; 61 for(int i = e[x]; i; i = edge[i].nex) { 62 int y = edge[i].v; 63 if(!edge[i].c || d[x] + 1 != d[y]) { 64 continue; 65 } 66 int temp = DFS(y, t, std::min(edge[i].c, maxF - Ans)); 67 if(!temp) { 68 d[y] = INF; 69 } 70 Ans += temp; 71 edge[i].c -= temp; 72 edge[i ^ 1].c += temp; 73 if(Ans == maxF) { 74 break; 75 } 76 } 77 return Ans; 78 } 79 80 inline int dinic(int s, int t) { 81 int Ans = 0; 82 while(BFS(s, t)) { 83 Ans += DFS(s, t, INF); 84 } 85 return Ans; 86 } 87 88 void DFS(int x, int k) { 89 vis[k][x] = 1; 90 for(int i = e[x]; i; i = edge[i].nex) { 91 int y = edge[i].v; 92 if(!edge[i ^ 1].c || vis[k][y]) { 93 continue; 94 } 95 DFS(y, k); 96 } 97 return; 98 } 99 100 inline bool check(int x, int mid) { 101 for(int k = 1; k <= s[x]; k++) { 102 for(int jj = topo[x][k].size() - 1; jj >= 0; jj--) { 103 int j = topo[x][k][jj]; 104 if(vis[x - mid - 1][j + n]) { 105 return 1; 106 } 107 } 108 } 109 return 0; 110 } 111 112 inline void solve() { 113 memset(vis[0], -1, sizeof(vis[0])); 114 int S = n + m + 1, T = n + m + 2; 115 for(int i = 1; i <= m; i++) { 116 add(n + i, T, b[i]); 117 } 118 for(int i = 1; i <= n; i++) { 119 add(S, i, 1); 120 mat[i] = 0; 121 for(int k = 1; k <= m; k++) { 122 TOP = top; 123 E[i] = e[i]; 124 for(int jj = topo[i][k].size() - 1; jj >= 0; jj--) { 125 int j = topo[i][k][jj]; 126 E[n + j] = e[n + j]; 127 add(i, n + j, 1); 128 } 129 int temp = dinic(S, T); 130 if(temp) { 131 mat[i] = k; 132 break; 133 } 134 else { 135 e[i] = E[i]; 136 for(int jj = topo[i][k].size() - 1; jj >= 0; jj--) { 137 int j = topo[i][k][jj]; 138 e[n + j] = E[n + j]; 139 } 140 top = TOP; 141 } 142 } 143 if(!mat[i]) { 144 mat[i] = m + 1; 145 } 146 DFS(T, i); 147 } 148 for(int i = 1; i <= n; i++) { 149 printf("%d ", mat[i]); 150 } 151 puts(""); 152 // first OVER 153 154 for(int i = 1; i <= n; i++) { 155 if(mat[i] <= s[i]) { 156 printf("0 "); 157 continue; 158 } 159 int l = 1, r = i; 160 while(l < r) { 161 int mid = (l + r) >> 1; 162 if(check(i, mid)) { 163 r = mid; 164 } 165 else { 166 l = mid + 1; 167 } 168 } 169 printf("%d ", r); 170 } 171 puts(""); 172 return; 173 } 174 175 inline void clear() { 176 memset(e, 0, sizeof(e)); 177 top = 1; 178 memset(vis, 0, sizeof(vis)); 179 return; 180 } 181 } 182 183 inline void solve() { 184 scanf("%d%d", &n, &m); 185 for(int i = 1; i <= m; i++) { 186 scanf("%d", &b[i]); 187 } 188 for(int i = 1; i <= n; i++) { 189 for(int j = 1; j <= m; j++) { 190 scanf("%d", &a[i][j]); 191 if(a[i][j]) { 192 topo[i][a[i][j]].push_back(j); 193 } 194 } 195 } 196 for(int i = 1; i <= n; i++) { 197 scanf("%d", &s[i]); 198 } 199 // read over 200 201 fl::solve(); 202 return; 203 } 204 205 inline void clear() { 206 for(int i = 1; i <= n; i++) { 207 for(int j = 1; j <= m; j++) { 208 topo[i][j].clear(); 209 } 210 } 211 fl::clear(); 212 return; 213 } 214 215 int main() { 216 217 int T; 218 scanf("%d%d", &T, &C); 219 while(T--) { 220 solve(); 221 if(T) { 222 clear(); 223 } 224 } 225 return 0; 226 }
AC代码
我发现D2T1都好毒瘤...屠龙勇士也是的。
转载于:https://www.cnblogs.com/huyufeifei/p/10143516.html
洛谷P4382 劈配相关推荐
- 洛谷P2507 [SCOI2008]配对 题解(dp+贪心)
洛谷P2507 [SCOI2008]配对 题解(dp+贪心) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1299251 链接题目地址:洛谷P2507 [S ...
- 洛谷1231 教辅的组成
洛谷1231 教辅的组成 https://www.luogu.org/problem/show?pid=1231 题目背景 滚粗了的HansBug在收拾旧语文书,然而他发现了什么奇妙的东西. 题目描述 ...
- 贪心策略摘果子(洛谷P1478题题解,Java语言描述)
题目要求 P1478题目链接 分析 本题的低配版题目链接 → 题解 那个题就是纯水题没啥可写的,我除了贴代码无话可说,但这题吧,虽然不算难,但也可一说. 建议大家移步这里 → 精辟题解 这位爷写了本题 ...
- BZOJ5251:[九省联考2018]劈配——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=5251 https://loj.ac/problem/2477 <-可以看数据 https: ...
- 信息学奥赛一本通 1844:【06NOIP提高组】金明的预算方案 | 洛谷 P1064 [NOIP2006 提高组] 金明的预算方案
[题目链接] ybt 1844:[06NOIP提高组]金明的预算方案 洛谷 P1064 [NOIP2006 提高组] 金明的预算方案 [题目考点] 1. 动态规划:分组背包 2. 动态规划:依赖背包 ...
- 洛谷P1991 无线通讯网
P1991 无线通讯网 170通过 539提交 题目提供者洛谷OnlineJudge 标签图论 难度普及+/提高 提交该题 讨论 题解 记录 最新讨论 怎么又炸了 为啥一直40!求解! UKE:inv ...
- 洛谷CF982B 题解
谢谢管理员大大给过 优先队列速通大法 hello!我又来水体了,不过嘛,相对来说这道题普及-不算水. 那我们就来研究研究吧. 先看题目 题目传送门 F1:0分暴力 一开始我也是闲的没事想要弄一下暴力做 ...
- 《终结者·洛谷》第4章
songhongyi摸了摸自己那已经恢复不少的身体,望了望窗外 房外已是大雪纷飞,街上一个人也没有···· 空与白之灵打开了洛谷,打开了题库,点进了P4379 空与白之灵进入了虚拟战场,直接套上了C党 ...
- 算法刷题【洛谷U193902】橡皮泥
异想之旅:本人原创博客完全手敲,绝对非搬运,全网不可能有重复:本人无团队,仅为技术爱好者进行分享,所有内容不牵扯广告.本人所有文章仅在CSDN.掘金和个人博客(一定是异想之旅域名)发布,除此之外全部是 ...
最新文章
- .NET2.0抓取网页全部链接【月儿原创】
- python pprint用法_Python中使用pprint函数进行格式化输出的教程
- 互联网大脑,城市大脑的“大脑”究竟什么含义?
- git学习(持续踩坑中
- 分布式系统开发的一些相关理论基础——CAP、ACID、BASE
- oracle备份片校验,oracle rman 备份日志单独备份和交叉校验
- infomix数据库版本sql_数据库周刊31丨华为openGauss 正式开源;7月数据库排行榜发布...
- 小程序上传图片到七牛云(支持多张上传,预览,删除)
- 前端学习(3152):react-hello-react之初始化react
- 【UI/UX】桌面GUI设计
- css cursor 鼠标手势
- SFP(Small Form-factor Pluggables)光模块
- faile什么意思_failed是什么意思,failed the test是什么意思
- 电脑ps4,Windows电脑玩PS4游戏,索尼:先来升级Win10吧
- ERROR - org.apache.flume.SinkRunner$PollingRunner.run(SinkRunner.java:158)] Unable to deliver event.
- codevs 5960 信使x
- 字符串str.format()方法的个人整理
- 信息学奥赛(NOIP/CSP-J/S)学习全目录
- API-String中的某些方法
- probuilder_使用ProBuilder自定义快照原型资产