题意:有三种操作:

1.新增一条边从y连向x,此前x没有父节点

2.x接到一份文件,(文件标号逐次递增),然后将这份文件一路上溯,让所有上溯的节点都接到这份文件

3.查询某个节点x是否接到过文件F

解法:

首先要知道一个性质,节点u在v的上溯路径上的话要满足: L[u]<=L[v] && R[u] >= R[v] (先进后出)

先将所有的边都读入,dfs得出L[u],R[u],然后将查询分为tot类(tot=总文件种数),记录每一类有那些地方查询了,然后如果type=2,那么记录这个type=2现在是第几类文件,都存下来以后备用。

再从1枚举到m,枚举每个输入,

如果type=1,那么将x,y集合合并,就算是建立了父子关系。

如果type=2,那么先得出现在得到的文件种类,再得到这个种类的所有查询,处理所有查询,得到u,v,先判断是否在一个集合中,然后再进行L[u]<=L[v] && R[u] >= R[v] 的判断,如果成立,说明u接到了v传来的该种类的文件。

如果type=3,先不处理,但是按照题意,也可以直接输出了。

最后输出。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <vector>
using namespace std;
#define N 100107 vector<int> G[N],query[N];
int fa[N],L[N],R[N],vis[N],Time,doc[N],f[N];
struct node{
int op,x,y;
}Q[N]; int findset(int x) {
if(x != fa[x]) fa[x] = findset(fa[x]);
return fa[x];
} void dfs(int u) {
vis[u] = ;
L[u] = ++Time;
for(int i=;i<G[u].size();i++) {
int v = G[u][i];
dfs(v);
}
R[u] = ++Time;
} int main()
{
int n,m,i,op,DOC = ,docnum;
memset(vis,,sizeof(vis));
scanf("%d%d",&n,&m);
for(i=;i<=n;i++) fa[i] = i;
for(i=;i<=m;i++) {
scanf("%d",&Q[i].op);
if(Q[i].op == ) {
scanf("%d%d",&Q[i].x,&Q[i].y);
G[Q[i].y].push_back(Q[i].x);
vis[Q[i].x] = ;
}
else if(Q[i].op == ) {
scanf("%d",&Q[i].x);
doc[i] = ++DOC; //第i个查询是查询第DOC种文档
}
else {
scanf("%d%d",&Q[i].x,&docnum);
query[docnum].push_back(i); //查询第docnum种文档的查询标号
}
}
Time = ;
memset(f,,sizeof(f));
for(i=;i<=n;i++)
if(!vis[i]) dfs(i); //处理出L[u],R[u]
for(i=;i<=m;i++) {
if(Q[i].op == ) {
int fx = findset(Q[i].x);
int fy = findset(Q[i].y);
fa[fx] = fy;
}
else if(Q[i].op == ) {
int now = doc[i]; //是第几种文档
int v = Q[i].x; //最底层签发者
for(int j=;j<query[now].size();j++) {
int ind = query[now][j];
int u = Q[ind].x; //查询目标
if(findset(u) == findset(v) && L[u] <= L[v] && R[u] >= R[v])
f[ind] = ;
}
}
}
for(i=;i<=m;i++) if(Q[i].op == ) {
if(f[i]) puts("YES");
else puts("NO");
}
return ;
}

CodeForces 466E Information Graph --树形转线性+并查集的更多相关文章

  1. Codeforces 466E Information Graph

    Information Graph 把询问离线之后就能随便搞了, 去check一下是不是祖先, 可以用倍增也能用dfs序. #include<bits/stdc++.h> #define ...

  2. Codeforces Round #582 (Div. 3)-G. Path Queries-并查集

    Codeforces Round #582 (Div. 3)-G. Path Queries-并查集 [Problem Description] 给你一棵树,求有多少条简单路径\((u,v)\),满足 ...

  3. Codeforces 938G(cdq分治+可撤销并查集+线性基)

    题意: 有一个无向连通图,支持三个操作: 1 x y d : 新建一条x和y的无向边,长度为d 2 x y    :删除x和y之间的无向边 3 x y    :询问x到y的所有路径中(可以绕环)最短的 ...

  4. Codeforces Beta Round #5 E. Bindian Signalizing 并查集

    E. Bindian Signalizing Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/problemset ...

  5. Codeforces Round #260 (Div. 1) C. Civilization 并查集,直径

    C. Civilization Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/455/probl ...

  6. Educational Codeforces Round 14 D. Swaps in Permutation (并查集orDFS)

    题目链接:http://codeforces.com/problemset/problem/691/D 给你n个数,各不相同,范围是1到n.然后是m行数a和b,表示下标为a的数和下标为b的数可以交换无 ...

  7. Codeforces 437D The Child and Zoo(贪心+并查集)

    题目链接:Codeforces 437D The Child and Zoo 题目大意:小孩子去參观动物园,动物园分非常多个区,每一个区有若干种动物,拥有的动物种数作为该区的权值.然后有m条路,每条路 ...

  8. Codeforces Round #541 (Div. 2) D(并查集+拓扑排序) F (并查集)

    D. Gourmet choice 链接:http://codeforces.com/contest/1131/problem/D 思路: =  的情况我们用并查集把他们扔到一个集合,然后根据 > ...

  9. Educational Codeforces Round 14 D. Swaps in Permutation 并查集

    D. Swaps in Permutation 题目连接: http://www.codeforces.com/contest/691/problem/D Description You are gi ...

随机推荐

  1. 实例之HTML标签属性

    鼠标放在图片上会显示说明文字的代码 <img src="图片地址" width=620 height=138 border=0 title="说明文字" ...

  2. SQL增强之Merge

    SQL Server 2008提供了一个增强的SQL命令Merge,用法参看MSDN:http://msdn.microsoft.com/zh-cn/library/bb510625.aspx 功能: ...

  3. Ubuntu开机黑屏,无法进入系统

    今天早上起来开机发现Ubuntu进不去了,启动项选择之后长时间的black of screen,击键盘.点鼠标毫无反应,后来实在等不下去了就按了一下电源键,以平时的性格就是强制关机的,这次轻轻碰一下就 ...

  4. Sharepoint学习笔记—习题系列--70-576习题解析 -(Q19-Q20)

    Question 19 You are designing a custom SharePoint 2010 solution package. It will include a feature t ...

  5. c++引用总结

    一.变量的引用: 引用:就是某一变量(目标)的一个别名,对引用的操作与对变量直接操作完全一样. 引用的声明方法:类型标识符 &引用名=目标变量名:  例:char ch;        cha ...

  6. Android studio 如何查看模拟器里面的文件

    1.查看SD卡里面的内容 2.看数据库

  7. Android自定义View滑动事件处理总结

    滑动处理需要用到的各种工具类: android.view.VelocityTracker android.view.OverScroller android.view.ViewConfiguratio ...

  8. objective-c系列-单例

    // 地球只有一个,所以声明一个地球对象就可以了,千万不能声明两个啊!同理,有时候一个类也有只能有一个对象的情况,例如服务器,只想存到一个里 // 面,这样子,下次才可以取出上次存的数据. //用全局 ...

  9. 浅谈JSON数据解析方法

    JSON数据解析 JSON是什么?? 如何把JSON数据解析出来 如何把一个字典转换为JSON JSON详细介绍 JSON(JavaScript Object Notation) 是一种轻量级的数据交 ...

  10. MJRefresh下拉刷新框架

    github下载地址:https://github.com/CoderMJLee/MJRefresh MJRefresh类结构图 self.userTableView.mj_footer = [MJR ...