题目链接:点击查看

题目大意:现在有k个人类需要从地球上转移到月球上去,现在有n个宇宙中转站,以及m个飞船周期性运载,每个飞船的载客都有一定的上限,但中转站的载客没有上限,现在给出每个飞船的路线,问最少需要多长时间才能将全部人类从地球运往月球

题目分析:一开始没太看懂题,更确切的说是看懂题了但提取不出模型,题目中的飞船其实是一刻不停的在周期性运转,类似于环形公交车一样,所以题目给出的样例答案是5,因为那个人在点2下车后需要等第二班公交车转一圈回来后再接上他才行,只能让人等公交车而不能让公交车等人

明白了飞船的运行规则后,我们可以发现,这就是一个关于时间的分层图,就可以直接建图了,借题解老哥的图一用:

除去源点S和汇点T外,可以视为一个n*m的矩阵,每一行代表的是时间,每一列代表的是中转站、地球、月球,这样以来就可以直接枚举时间,建边,不断在残余网络上跑最大流,直到最大流大于等于人类的数量就可以退出了

还有一个需要特判的地方,就是无论怎么样都到不了月球的情况,这个我们直接用并查集维护一下,将每个飞船的航线视为一个集合,最后不断合并,看看月球和地球是否在一个集合中就可以了

通过这个题学到的知识,最主要的还是需要弄明白题意,直接提取模型的困难度实在是太大了,需要一步步将每个操作拆出来,每个操作的描述越简单越好,最后再拼凑成需要提取的模型,根据模型建图,这大概就是网络流通用的解题思路吧,有时候一些题目需要优化,这个也是网络流的一大难点,如何用现学的知识将其时空复杂度各种优化,直至满足题目给出的资源限制,说到底还是需要多做题多总结

关于这个题目就是因为时间复杂度不太会计算,导致不敢直接暴力枚举,怕超时,最后才无功而返,算是长记性了吧

代码:

#include<iostream>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<climits>
#include<cmath>
#include<cctype>
#include<stack>
#include<queue>
#include<list>
#include<vector>
#include<set>
#include<map>
#include<sstream>
#include<unordered_map>
using namespace std;typedef long long LL;const int inf=0x3f3f3f3f;const int N=1e5+100;struct Edge
{int to,w,next;
}edge[N];//边数int head[N],cnt,maze[25][25],num[25],p[25],fa[N];void addedge(int u,int v,int w)
{edge[cnt].to=v;edge[cnt].w=w;edge[cnt].next=head[u];head[u]=cnt++;edge[cnt].to=u;edge[cnt].w=0;//反向边边权设置为0edge[cnt].next=head[v];head[v]=cnt++;
}int d[N],now[N];//深度 当前弧优化bool bfs(int s,int t)//寻找增广路
{memset(d,0,sizeof(d));queue<int>q;q.push(s);now[s]=head[s];d[s]=1;while(!q.empty()){int u=q.front();q.pop();for(int i=head[u];i!=-1;i=edge[i].next){int v=edge[i].to;int w=edge[i].w;if(d[v])continue;if(!w)continue;d[v]=d[u]+1;now[v]=head[v];q.push(v);if(v==t)return true;}}return false;
}int dinic(int x,int t,int flow)//更新答案
{if(x==t)return flow;int rest=flow,i;for(i=now[x];i!=-1&&rest;i=edge[i].next){int v=edge[i].to;int w=edge[i].w;if(w&&d[v]==d[x]+1){int k=dinic(v,t,min(rest,w));if(!k)d[v]=0;edge[i].w-=k;edge[i^1].w+=k;rest-=k;}}now[x]=i;return flow-rest;
}void init()
{for(int i=0;i<N;i++)fa[i]=i;memset(head,-1,sizeof(head));cnt=0;
}int solve(int st,int ed)
{int ans=0,flow;while(bfs(st,ed))while(flow=dinic(st,ed,inf))ans+=flow;return ans;
}int get_id(int x,int y)//x:时间 y:太空站
{return x*15+y;
} int find(int x)
{return fa[x]==x?x:fa[x]=find(fa[x]);
}void merge(int x,int y)
{int xx=find(x);int yy=find(y);if(xx!=yy)fa[xx]=yy;
}int main()
{
//  freopen("input.txt","r",stdin);
//  ios::sync_with_stdio(false);init();int n,m,k,st=N-1,ed=st-1;scanf("%d%d%d",&n,&m,&k);for(int i=1;i<=m;i++){scanf("%d%d",&p[i],&num[i]);for(int j=0;j<num[i];j++){scanf("%d",&maze[i][j]);if(maze[i][j]==0)maze[i][j]=n+1;if(maze[i][j]==-1)maze[i][j]=n+2;if(j!=0)merge(maze[i][j],maze[i][j-1]);}}if(find(n+1)!=find(n+2))return 0*printf("0\n");int time=0,max_flow=0;addedge(st,get_id(time,n+1),inf);addedge(get_id(time,n+2),ed,inf);while(++time)//n+1:地球 n+2:月球 {addedge(st,get_id(time,n+1),inf);addedge(get_id(time,n+2),ed,inf);for(int i=1;i<=n;i++)addedge(get_id(time-1,i),get_id(time,i),inf);for(int i=1;i<=m;i++){int x=(time-1)%num[i];int y=time%num[i];addedge(get_id(time-1,maze[i][x]),get_id(time,maze[i][y]),p[i]);}max_flow+=solve(st,ed);if(max_flow>=k)return 0*printf("%d\n",time);}return 0;
}

洛谷 - P2754 [CTSC1999]家园(最大流+并查集)相关推荐

  1. 家园 / 星际转移问题(洛谷P2754 分层图+最大流)

    再一次感觉网络流太神奇了qwq 题目链接:[星际转移问题](P4009 汽车加油行驶问题 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)) 受到之前那道[汽车加油行驶问题](P400 ...

  2. 洛谷P3247 [HNOI2016]最小公倍数 [分块,并查集]

    洛谷 思路 显然,为了达到这个最小公倍数,只能走\(a,b\)不是很大的边. 即,当前询问的是\(A,B\),那么我们只能走\(a\leq A,b\leq B\)的边. 然而,为了达到这最小公倍数,又 ...

  3. 洛谷P3295 [SCOI2016]萌萌哒(倍增+并查集)

    传送门 思路太妙了啊-- 容易才怪想到暴力,把区间内的每一个数字用并查集维护相等,然后设最后总共有$k$个并查集,那么答案就是$9*10^{k-1}$(因为第一位不能为0) 考虑倍增.我们设$f[i] ...

  4. 洛谷P4768 [NOI2018]归程 [可持久化并查集,Dijkstra]

    题目传送门 归程 格式难调,题面就不放了. 分析: 之前同步赛的时候反正就一脸懵逼,然后场场暴力大战,现在呢,还是不会$Kruskal$重构树,于是就拿可持久化并查集做. 但是之前做可持久化并查集的时 ...

  5. 【洛谷P4997】不围棋【并查集】【模拟】

    题目大意: 题目链接:https://www.luogu.org/problemnew/show/P4997 「不围棋」是一种非常有趣的棋类游戏. 大家都知道,围棋的「气」是指一个棋子所在的联通块相邻 ...

  6. P2754 [CTSC1999]家园 / 星际转移问题(网络流)

    P2754 [CTSC1999]家园 / 星际转移问题 经典问题,利用分层图来跑网络流.

  7. HDU 3081 Marriage Match II (并查集+二分+最大流 | 并查集+二分图匹配)

    题意:n 个男生.n个女生玩游戏,每个女生都可以和她不讨厌的男生结婚,此外她的朋友如果也不讨厌这个男生,也可以和他结婚:对于女生,如果A和B是朋友,B和C是朋友,那么A和C也是朋友.每次游戏女生会找一 ...

  8. 洛谷P3980 志愿者招募——费用流

    洛谷P3980 [NOI2008]志愿者招募--费用流 题目介绍 题目描述 输入格式 输出格式 测试样例 题解 代码 题目介绍 题目描述 链接: 传送门. 申奥成功后,布布经过不懈努力,终于成为奥组委 ...

  9. 洛谷P2754:[CTSC1999]家园 / 星际转移问题(网络流)

    解析 容易想到对每个时间的空间站都建一个点. 然后发现循环问题很难搞. 然后我就一直想从 lcm 下文章,结果 lcm 可以到3e5,于是就寄了- qwq 注意到本题的数据范围极小! 那个3e5云云是 ...

最新文章

  1. babyos (三)——利用BIOS INT 0x13读取软盘
  2. luogu P3379 【模板】最近公共祖先(LCA)
  3. 错误:android.util.SuperNotCalledException
  4. 全球与中国激光投影设备市场前景规划与发展战略建议报告2022-2028年版
  5. 数据库中什么是主键,什么是外键?
  6. js实现线路流动_52期:实现redux与reactredux
  7. JS中URL编码解码
  8. javascript --- 变量提升的理解
  9. 递归修改子目录及文件的权限
  10. ThinkPHP文件目录说明
  11. netty框架实现websocket达到高并发
  12. mysql econnreset_javascript - 节点Js mysql(和mysql2)ECONNRESET - 堆栈内存溢出
  13. JavaScript高级编程之树节点搜索过滤的设计和实现
  14. B站(云e办)SpringBoot实战练习的Sql文件、前端Vue源码、后端springboot源码
  15. Froala 编辑器设置表格页脚
  16. qq传输文件为什么服务器忙,qq传送离线 接收文件很慢怎么回事
  17. mysql的cnf配置文件全解析
  18. ibm tivoli_通过IBM Tivoli Access Manager WebSEAL单一登录到IBM WebSphere Portal
  19. mysql带中文日期转换_【MySQL】日期时间格式转换_MySQL
  20. python mongodb分页查询_python数据库分页查询语句

热门文章

  1. 向量值函数在计算机工程与应用,拟Newton法在高阶矩阵中的应用-计算机工程与应用.PDF...
  2. Nginx的Gzip模块配置指令(三)
  3. 类的加载连接和初始化
  4. 角色操作-角色添加代码实现
  5. JasperReport:声明周期
  6. 方法的重写-扩展父类方法,super对象调用父类方法
  7. linux下设置定时任务,linux下定时任务设置
  8. Activemq-In-action(三)
  9. skywalking环境搭建
  10. mkdir和mkdir-p的区别