window.cnblogsConfig = {//可以放多张照片,应该是在每一个博文上面的图片,如果是多张的话,那么就随机换的。 homeTopImg: [ "https://cdn.luogu.com.cn/upload/image_hosting/clcd8ydf.png", "https://cdn.luogu.com.cn/upload/image_hosting/clcd8ydf.png" ], }

CF320B解题报告

题意

有一些区间,当且仅当一个区间包含另一个区间的起点或终点时,这两个区间可以互相到达。

需要处理两种操作:

  • 添加一个区间,保证这个区间的长度严格大于之前区间的长度。
  • 询问一个区间是否能到达另一个区间。

分析

不难看出可以建图然后 dfs 一遍看起点能不能到达终点。

对于添加操作,相当于建图,如果区间 x 能到达区间 y(满足题面上的条件),那么就连一条边,建反边同理(可以从 y 转移到 x)。

对于查询操作,直接 dfs 看能不能从 a 区间到达 b 区间,dfs 部分不再赘述,最后输出。

代码

#include <bits/stdc++.h> using namespace std; int n, len, flag; int l[105], r[105], vis[105]; vector<int> g[105]; void dfs(int x, int ex){ if (flag) return ; if (x == ex){//走到了 flag = 1; return ; } vis[x] = 1; for (int i = 0; i < g[x].size(); i++){ int v = g[x][i]; if (vis[v] == 0) dfs(v, ex); } } int main(){ cin >> n; for (int i = 1, opt, x, y; i <= n; i++){ cin >> opt >> x >> y; if (opt == 1){ l[++len] = x, r[len] = y; for (int i = 1; i < len; i++){//这里只需要遍历已经添加过的边,后面加进来的边也会再来一次,建反边时相当于从这里建了一条正边 if ((l[i] < l[len] && l[len] < r[i]) || (l[i] < r[len] && r[len] < r[i])) g[len].push_back(i);//满足条件建边 if ((l[len] < l[i] && l[i] < r[len]) || (l[len] < r[i] && r[i] < r[len])) g[i].push_back(len);//建反向边 } } else{ memset(vis, 0, sizeof(vis));//记录每个点是否走过 flag = 0; dfs(x, y);//看能不能从x移动到y if (flag == 1) cout << "YES\n"; else cout << "NO\n"; } } return 0; }

__EOF__

本文作者ccf-ioi
本文链接https://www.cnblogs.com/ccf-ioi/p/17971620.html
关于博主:I AK IOI
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   CCF_IOI  阅读(26)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?
点击右上角即可分享
微信分享提示