题目链接:https://www.luogu.org/problemnew/show/P2754

知识点:  最大流

解题思路:

  先用 \(DFS\) 判断是否无解。

  从时刻 \(0\) 开始枚举答案,从飞船此刻的位置往下一时刻的位置连边,容量为飞船的载客量,然后在上一刻的残量网络的基础上跑 \(sap\),将最大流累加起来,当最大流的累加和大于或等于 \(k\) 时,便可得出答案。

  对于同一个位置的不同时刻,要用不同的点代表,并且把他们按照时间的先后顺序连起来,容量为 \(INF\);对于代表地球的任一时刻的点,从源点连边指向它们,容量为 \(INF\);对于代表月亮的任一时刻的点,连一条指向源点的边,容量也为 \(INF\)。

AC代码:

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. const int MAXN=;
  5. const int MAXM=;
  6. const int INF=0x3f3f3f3f;
  7. struct Edge{
  8. int to,Next,cap,flow;
  9. }edge[MAXM];
  10. int tol;
  11. int head[MAXN];
  12. int gap[MAXN],dep[MAXN],cur[MAXN];
  13. void init(){
  14. tol=;
  15. memset(head,-,sizeof(head));
  16. }
  17. void addedge(int u,int v,int w,int rw=){
  18. edge[tol].to=v; edge[tol].cap=w; edge[tol].flow=;
  19. edge[tol].Next=head[u]; head[u]=tol++;
  20. edge[tol].to=u; edge[tol].cap=rw; edge[tol].flow=;
  21. edge[tol].Next=head[v]; head[v]=tol++;
  22. }
  23. int Q[MAXN];
  24. void BFS(int start,int ends){
  25. memset(dep,-,sizeof(dep));
  26. memset(gap,,sizeof(gap));
  27. gap[]=;
  28. int fronts=,rear=;
  29. dep[ends]=;
  30. Q[rear++]=ends;
  31. while(fronts!=rear){
  32. int u=Q[fronts++];
  33. for(int i=head[u];i!=-;i=edge[i].Next){
  34. int v=edge[i].to;
  35. if(dep[v]!=-) continue;
  36. Q[rear++]=v;
  37. dep[v]=dep[u]+;
  38. gap[dep[v]]++;
  39. }
  40. }
  41. }
  42. int S[MAXN];
  43. int sap(int start,int ends,int N){
  44. BFS(start,ends);
  45. memcpy(cur,head,sizeof(head));
  46. int top=;
  47. int u=start;
  48. int ans=;
  49. while(dep[start]<N){
  50. if(u==ends){
  51. int Min=INF;
  52. int inser;
  53. for(int i=;i<top;i++){
  54. if(Min>edge[S[i]].cap-edge[S[i]].flow){
  55. Min=edge[S[i]].cap-edge[S[i]].flow;
  56. inser=i;
  57. }
  58. }
  59. for(int i=;i<top;i++){
  60. edge[S[i]].flow+=Min;
  61. edge[S[i]^].flow-=Min;
  62. }
  63. ans+=Min;
  64. top=inser;
  65. u=edge[S[top]^].to;
  66. continue;
  67. }
  68. bool flag=false;
  69. int v;
  70. for(int i=cur[u];i!=-;i=edge[i].Next){
  71. v=edge[i].to;
  72. if(edge[i].cap-edge[i].flow && dep[v]+==dep[u]){
  73. flag=true;
  74. cur[u]=i;
  75. break;
  76. }
  77. }
  78. if(flag){
  79. S[top++]=cur[u];
  80. u=v;
  81. continue;
  82. }
  83. int Min=N;
  84. for(int i=head[u];i!=-;i=edge[i].Next){
  85. if(edge[i].cap-edge[i].flow && dep[edge[i].to]<Min){
  86. Min=dep[edge[i].to];
  87. cur[u]=i;
  88. }
  89. }
  90. gap[dep[u]]--;
  91. if(!gap[dep[u]]) return ans;
  92. dep[u]=Min+;
  93. gap[dep[u]]++;
  94. if(u!=start) u=edge[S[--top]^].to;
  95. }
  96. return ans;
  97. }
  98.  
  99. int h[],p[];
  100. int r[][];
  101. vector<int> G[];
  102. bool viss[];
  103. void dfs(int rt,int moon){
  104. viss[rt]=true;
  105. if(rt==moon) return;
  106. for(int i=;i<G[rt].size();i++){
  107. int v=G[rt][i];
  108. if(!viss[v]) dfs(v,moon);
  109. }
  110. }
  111.  
  112. int main(){
  113. int n1,m1,k1;
  114. scanf("%d%d%d",&n1,&m1,&k1);
  115. for(int i=;i<m1;i++){
  116. scanf("%d%d",&h[i],&p[i]);
  117. for(int j=;j<p[i];j++){
  118. scanf("%d",&r[i][j]);
  119. if(r[i][j]==-)
  120. r[i][j]=n1+;
  121. }
  122. for(int j=;j<p[i];j++){
  123. int u=r[i][j],v=r[i][(j+)%p[i]];
  124. G[u].push_back(v);
  125. }
  126. }
  127. dfs(,n1+);
  128. if(!viss[n1+]){
  129. puts("");
  130. return ;
  131. }
  132. init();
  133. int s=,t=;
  134. int now=,add=,had=;
  135. int tot=+(n1+)*;
  136. addedge(s,add,INF);
  137. addedge(add+n1+,t,INF);
  138. while(){
  139. for(int i=;i<m1;i++){
  140. int u=r[i][now%p[i]]+add,v=r[i][(now+)%p[i]]+add+n1+;
  141. addedge(u,v,h[i]);
  142. }
  143. for(int i=;i<n1+;i++)
  144. addedge(i+add,i+add+n1+,INF);
  145. addedge(add+n1++n1+,t,INF);
  146. had+=sap(s,t,tot);
  147. if(had>=k1){
  148. printf("%d\n",now+);
  149. return ;
  150. }
  151. now++;
  152. tot+=n1+;
  153. add+=n1+;
  154. }
  155. }

洛谷P2754 [CTSC1999]家园的更多相关文章

  1. 洛谷P2754 [CTSC1999]家园(最大流)

    传送门 这题思路太强了……大佬们怎么想到的……我这菜鸡根本想不出来…… 先判断是否能到达,对每一艘飞船能到的地方用并查集合并一下,最后判断一下是否连通 然后考虑几天怎么判断,我们可以枚举. 每一个点表 ...

  2. 洛谷2754 [CTSC1999]家园

    题目链接:[CTSC1999]家园 这个题目我们不是很好在做网络流的时候判断是否有解,因此我们考虑分开来做 对于是否有解的判断,我们唯一需要解决的是飞船的周期停泊问题,对于这个问题,我们可以用并查集解 ...

  3. 网络流24题之星际转移问题(洛谷P2754)

    洛谷 P2754 题目背景 none! 题目描述 由于人类对自然资源的消耗,人们意识到大约在 2300 年之后,地球就不能再居住了.于是在月球上建立了新的绿地,以便在需要时移民.令人意想不到的是,21 ...

  4. 【洛谷 P2754】 [CTSC1999]家园(最大流)

    题目链接 突然发现Dinic很好写诶.. 第一次数组开小了,玄学\(WA\),what?数据范围描述有误? 分层图,每天为一层. 把上一天的每个空间站向这一天连一条流量为inf的边,表示可以原地不动. ...

  5. 网络流24题 P2754 [CTSC1999]家园

    思路 如图,建立分层图跑dinic 每次在残余网络里加边继续跑 跑到ans>=k时候的i就是答案 诶呀啊,忘记弄箭头了,最后一列是向上的箭头,不过聪明的你们应该没啥影响 代码 #include ...

  6. P2754 [CTSC1999]家园

    传送门 人在各个太空站流动,所以显然的网络流模型 因为不同时间能走的边不同,所以显然按时间拆点 但是因为不知道要多少时间,所以要枚举时间,动态拆点 每一点向下一个时间的同一点连流量为 $INF$ 的边 ...

  7. 洛谷 P2754 星际转移问题【最大流】

    判无解的方法非常粗暴:快T了还是没有合法方案,就是无解. 然后枚举答案,对于每一天都建一套太空站,s连地球,t连月球,上一天的太空站连向这一天的太空站,流量均为inf.然后对于每个飞船,上一天的停靠站 ...

  8. luogu P2754 [CTSC1999]家园

    本题是分层图最大流问题,相当于按时间拆点,每个当前点向下一点的下一时间层连点,每一层有n+1个点 #include<bits/stdc++.h> using namespace std; ...

  9. 最小生成树+LCA【洛谷 P2245】 星际导航

    [洛谷 P2245] 星际导航 题目描述 sideman做好了回到Gliese 星球的硬件准备,但是sideman的导航系统还没有完全设计好.为了方便起见,我们可以认为宇宙是一张有N 个顶点和M 条边 ...

随机推荐

  1. 2.Python是什么?使用Python的好处是什么?

    Python是什么?使用Python的好处是什么? 答: Python is a programming language with objects, modules, threads, except ...

  2. Entity framework 加载多层相关实体数据

    Entity framework有3种加载数据的方式:懒汉式(Lazy loading),饿汉式(Eager loading),显示加载(Explicit loading).3种加载方式有各自的优缺点 ...

  3. postman(动态数据获取)

    一:返回报文为 json 格式 示例:因为充值记录接口中需要用到登录接口返回报文中的信息如下 1.以获取token(JWT)和uid为例 2.在登录接口的tests中写入代码(因为登录接口报文信息中有 ...

  4. 去 HBase,Kylin on Parquet 性能表现如何?

    Kylin on HBase 方案经过长时间的发展已经比较成熟,但也存在着局限性,因此,Kyligence 推出了 Kylin on Parquet 方案(了解详情戳此处).通过标准数据集测试,与仍采 ...

  5. MongoDB JAVA开发

    简介 MongoDB是一个基于内存的NoSql(非关系型数据库).具有NoSql的特点,读写快(key-value),不适合持久化但都提供此功能. 用途 我用来存放页面模板 用法 依赖 <dep ...

  6. spring的单元测试

    如果spring 4.3.18这个版本的spring要使用junit,需要使用junit的junit-4.12之上的版本.使用这个版本junit的时 候需要引入hamcrest-all的jar包.之前 ...

  7. Spring Cloud学习 之 Spring Cloud Ribbon(负载均衡器源码分析)

    文章目录 AbstractLoadBalancer: BaseLoadBalancer: DynamicServerListLoadBalancer: ServerList: ServerListUp ...

  8. 王颖奇 20171010129《面向对象程序设计(java)》第十七周学习总结

    实验十七  线程同步控制 实验时间 2018-12-10 学习总结: 1.Java通过多线程的并发运行提高系统资源利用 率,改善系统性能. 2.假设有两个或两个以上的线程共享 某个对象,每个线程都调用 ...

  9. 201771010113 李婷华 《面向java对象程序设计(Java)》第四章学习总结

    一. 理论知识部分 第四章 对象与类 本章主要讲述面向对象程序设计.如何创建标准Java类库中的类对象.如何编写自己的类. 1.面向对象程序设计的几个主要概念: 抽象数据类型.类和对象.封装.类层次( ...

  10. 【Spark】SparkStreaming的容错机制

    文章目录 检查点机制 驱动器程序容错 工作节点容错 接收器容错 处理保证 检查点机制 Metadata checkpointing -- 将定义流计算的信息存入容错的系统如HDFS. Data che ...