codeforces466E 并查集+离线处理+dfs
来源:互联网 发布:淘宝上怎么搜高仿手表 编辑:程序博客网 时间:2024/04/27 17:23
题目大意:一开始有n个员工,它们互相独立,现有三种操作:
1 x y y称为x的上级
2 x 从x发起一份文件,依次向上级传阅。文件编号依次递增
3 x y 问x是否查阅过编号为y的文件
思路:最暴力的解法就是模拟他的规则,但是这样明显超时。此时,想到了离线操作。我们可以用并查集确定每份文件的发起者和终结者,即文件移动的范围。。然后对于每次询问可以拆成两个标记 ,假设查询x是否浏览过第k号文件,第k号文件的范围为u-v,那么在最后dfs时,遍历到x,判断是否经过u;遍历到v时,判断是否经过x。如果两个都满足,则是YES。(此处参考他人做法)
#include <iostream>#include <cstdio>#include <string>#include <cstring>#include <fstream>#include <algorithm>#include <cmath>#include <queue>#include <stack>#include <vector>#include <map>#include <set>#include <iomanip>using namespace std;//#pragma comment(linker, "/STACK:102400000,102400000")#define maxn 200005#define MOD 1000000007#define mem(a , b) memset(a , b , sizeof(a))#define LL long long#define ULL unsigned long longtypedef pair<int , int> pii;const long long INF=0x3fffffff;int n , m;int fa[maxn] , vis[maxn] , ans[maxn];vector<int>v[maxn];vector<pii>q[maxn];struct node{ int st , ed;}rang[maxn] , tmp;int findfa(int a ){ if(fa[a] == a) return a; else return fa[a] = findfa(fa[a] );}void dfs(int u ){ vis[u] = 1; for (int i = 0; i < v[u].size(); i++) dfs(v[u][i]); for (int i = 0; i < q[u].size(); i++) { int v = q[u][i].first, id = q[u][i].second; if (vis[v]) ans[id]++; } vis[u] = 0;}int main(){ while(scanf("%d %d" , &n , &m) != EOF) { mem(ans , 0 ) ; int op , x , y , pos = 1 , K = 1; for(int i = 0 ; i <= n ; i ++) fa[i] = i , v[i].clear(); for(int i = 1 ; i <= m ; i ++) { scanf("%d" , &op); if(op == 1) { scanf("%d %d" , &x , &y); fa[x] = y; v[y].push_back(x); } else if(op == 2) { scanf("%d" , &x); rang[pos].st = x; rang[pos++].ed = findfa(x ); } else { scanf("%d %d" , &x , &y); pii u = make_pair(rang[y].ed , rang[y].st); q[x].push_back(make_pair(u.first, K)); //将K号文件终止节点加入x ,当dfs到x时,判断是否经过文件的终止点 q[u.second].push_back(make_pair(x, K)); // 将查询的x放入K号文件的起点,dfs到K的起点时,判断是否经过x K++; } } for(int i = 1 ; i <= n ;i ++) { if(fa[i] == i) dfs(i); } for(int i = 1 ; i < K ; i ++) { if(ans[i] == 2) printf("YES\n"); else printf("NO\n"); } } return 0;}
0 0
- codeforces466E 并查集+离线处理+dfs
- Codeforces Round #266 (Div. 2) E codeforces466e(dfs序+并查集)
- Codeforces 466E Information Graph【Dfs处理父子关系+并查集+离线查询】好题!
- fzu 2059 并查集+离线处理
- hdu5441 离线处理+并查集
- HDU 5441 离线处理+并查集
- hdu 离线处理+并查集
- hdu 5441 离线处理+并查集
- POJ 1986 LCA 离线算法 dfs+并查集
- poj 1986LCA离线dfs+并查集
- 【LCA】Tarjan离线算法(并查集+dfs)模板
- hihoCoder1067 最近公共祖先离线查询 dfs + 并查集
- ZOJ 3261 Connections in GalaxyWar(并查集:离线处理)
- 【CodeForces】466E Information Graph 离线处理+并查集
- 【FZU】Problem 2059 MM(离线处理并查集)
- BZOJ-1015 StarWar星球大战 并查集+离线处理
- 【bzoj4320】【ShangHai2006 Homework】【并查集+离线处理】
- 4320: ShangHai2006 Homework 并查集+离线处理 思路题
- Spark SQL和DataFrame的学习总结
- alibaba的FastJson(高性能JSON开发包)
- c++第五次上机实验:项目一-奇数偶数分组
- 第10,11周 阅读程序写出运行结果 (3)
- Android Activity为什么要细化出onCreate、onStart、onResume、onPause、onStop、onDesdroy这么多方法让应用去重
- codeforces466E 并查集+离线处理+dfs
- C语言将16进制的数转换为字符串的方法
- Etag 笔记
- C++拷贝构造函数的调用时机,如没有重载等号操作符,需重写使用深拷贝
- a simple stone game--k倍动态规划减法游戏
- 如何实现手机缓存清理的功能
- iOS中利用 runtime 一键改变字体
- oracle 存储过程循环执行update语句
- 手机游戏上线前的准备