不知道这个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 劈配相关推荐

  1. 洛谷P2507 [SCOI2008]配对 题解(dp+贪心)

    洛谷P2507 [SCOI2008]配对 题解(dp+贪心) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1299251 链接题目地址:洛谷P2507 [S ...

  2. 洛谷1231 教辅的组成

    洛谷1231 教辅的组成 https://www.luogu.org/problem/show?pid=1231 题目背景 滚粗了的HansBug在收拾旧语文书,然而他发现了什么奇妙的东西. 题目描述 ...

  3. 贪心策略摘果子(洛谷P1478题题解,Java语言描述)

    题目要求 P1478题目链接 分析 本题的低配版题目链接 → 题解 那个题就是纯水题没啥可写的,我除了贴代码无话可说,但这题吧,虽然不算难,但也可一说. 建议大家移步这里 → 精辟题解 这位爷写了本题 ...

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

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

  5. 信息学奥赛一本通 1844:【06NOIP提高组】金明的预算方案 | 洛谷 P1064 [NOIP2006 提高组] 金明的预算方案

    [题目链接] ybt 1844:[06NOIP提高组]金明的预算方案 洛谷 P1064 [NOIP2006 提高组] 金明的预算方案 [题目考点] 1. 动态规划:分组背包 2. 动态规划:依赖背包 ...

  6. 洛谷P1991 无线通讯网

    P1991 无线通讯网 170通过 539提交 题目提供者洛谷OnlineJudge 标签图论 难度普及+/提高 提交该题 讨论 题解 记录 最新讨论 怎么又炸了 为啥一直40!求解! UKE:inv ...

  7. 洛谷CF982B 题解

    谢谢管理员大大给过 优先队列速通大法 hello!我又来水体了,不过嘛,相对来说这道题普及-不算水. 那我们就来研究研究吧. 先看题目 题目传送门 F1:0分暴力 一开始我也是闲的没事想要弄一下暴力做 ...

  8. 《终结者·洛谷》第4章

    songhongyi摸了摸自己那已经恢复不少的身体,望了望窗外 房外已是大雪纷飞,街上一个人也没有···· 空与白之灵打开了洛谷,打开了题库,点进了P4379 空与白之灵进入了虚拟战场,直接套上了C党 ...

  9. 算法刷题【洛谷U193902】橡皮泥

    异想之旅:本人原创博客完全手敲,绝对非搬运,全网不可能有重复:本人无团队,仅为技术爱好者进行分享,所有内容不牵扯广告.本人所有文章仅在CSDN.掘金和个人博客(一定是异想之旅域名)发布,除此之外全部是 ...

最新文章

  1. .NET2.0抓取网页全部链接【月儿原创】
  2. python pprint用法_Python中使用pprint函数进行格式化输出的教程
  3. 互联网大脑,城市大脑的“大脑”究竟什么含义?
  4. git学习(持续踩坑中
  5. 分布式系统开发的一些相关理论基础——CAP、ACID、BASE
  6. oracle备份片校验,oracle rman 备份日志单独备份和交叉校验
  7. infomix数据库版本sql_数据库周刊31丨华为openGauss 正式开源;7月数据库排行榜发布...
  8. 小程序上传图片到七牛云(支持多张上传,预览,删除)
  9. 前端学习(3152):react-hello-react之初始化react
  10. 【UI/UX】桌面GUI设计
  11. css cursor 鼠标手势
  12. SFP(Small Form-factor Pluggables)光模块
  13. faile什么意思_failed是什么意思,failed the test是什么意思
  14. 电脑ps4,Windows电脑玩PS4游戏,索尼:先来升级Win10吧
  15. ERROR - org.apache.flume.SinkRunner$PollingRunner.run(SinkRunner.java:158)] Unable to deliver event.
  16. codevs 5960 信使x
  17. 字符串str.format()方法的个人整理
  18. 信息学奥赛(NOIP/CSP-J/S)学习全目录
  19. API-String中的某些方法
  20. probuilder_使用ProBuilder自定义快照原型资产

热门文章

  1. 动态规划经典例题:乘积最大连续子数组
  2. 为什么socket接收大数据的时候接收不完全,出现丢包?
  3. MOVW 和 rep
  4. 一对多查询,合并成一条数据
  5. 设置IE安全并打开自动仿冒网站筛选器和IE安全设置
  6. Java获取正在执行的函数名
  7. 除了组件超配光伏效率还能如何提升?
  8. PHP 用each 和list配合 达到map的效果
  9. nginx的url重写[rewrite规则和参考]
  10. NeedforSpeed:SHIFT