LCA tarjan+并查集POJ1470

https://www.cnblogs.com/JVxie/p/4854719.html

不错的一篇博客啊,让我觉得LCA这么高大上的算法不是很难啊,嘻嘻嘻

这是个离线算法,现在的粗略理解是输入完毕询问完毕后进行解决的算法

用了并查集

1···选取根节点

2···逐个dfs访问所选节点所有的子节点v

  3···1··对于子节点的dfs访问到头之后

  3···2··标记,进行询问查询

  3···3··如果查询的点访问过,输出其目前祖先

  4···回溯,合并边,更新pre数组(并查集)

5.所有节点访问完毕,结束

1.任选一个点为根节点,从根节点开始。

2.遍历该点u所有子节点v,并标记这些子节点v已被访问过。

3.若是v还有子节点,返回2,否则下一步。

4.合并v到u上。

5.寻找与当前点u有询问关系的点v。

6.若是v已经被访问过了,则可以确认u和v的最近公共祖先为v被合并到的父亲节点

模拟别人打了一下代码

#include <iostream>
#include <cstdio>
#include <string.h>
using namespace std;
const int maxn = 1000;
const int maxm = 1000; struct node{
int to,pre;
}e[maxn * maxn],q[maxn * maxn];
int pre[maxn];
bool vis[maxn];
int id[maxn],cnt;
int idq[maxn],cntq;
int in[maxn];
int ans[maxn];
int root;
void init(int n)
{
memset(id,-1,sizeof(id));
memset(idq,-1,sizeof(idq));
cntq = 0;
cnt = 0;
memset(in,0,sizeof(in));
memset(ans,0,sizeof(ans));
memset(vis,0,sizeof(vis));
for(int i = 0;i <= n;i++)
pre[i] = i;
}
void add(int from,int to)
{
e[cnt].to = to;
e[cnt].pre = id[from];
id[from] = cnt++;
}
void addq(int from,int to)
{
q[cntq].to = to;
q[cntq].pre = idq[from];
idq[from] = cntq++;
}
int Find(int x)
{
if(pre[x] == x)return x;
return pre[x] = Find(pre[x]);
}
void join(int u,int v)
{
int fu = Find(u);
int fv = Find(v);
pre[fv] = fu;
}
void LCA(int rt)
{
for(int i = id[rt];~i;i = e[i].pre)
{
int to = e[i].to;
LCA(to);
join(rt,to);
}
vis[rt] = 1;
for(int i = idq[rt];~i;i = q[i].pre)
{
int que = q[i].to;
if(vis[que])
ans[Find(que)]++;
}
}
int main()
{
int n;
while(~scanf("%d",&n))
{
init(n);
int x,y,z;
for(int i = 0;i < n;i++)
{
scanf("%d:(%d)",&x,&y);
for(int j = 0;j < y;j++)
{
scanf("%d",&z);
in[z] = 1;
add(x,z);
}
}
int t;
scanf("%d",&t);
while(t--)
{
while(getchar() !='(');
scanf("%d%d",&x,&y);
addq(x,y);
addq(y,x);
}
while(getchar() != ')');
for(int i = 1;i <= n;i++)
if(!in[i])root = i;
LCA(root);
for(int i = 1;i <= n;i++)
{
if(ans[i] != 0)
printf("%d:%d\n",i,ans[i]);
}
}
return 0;
}

现在我要自己去大一下模板提啦

http://node2.vjmirror.rainng.com/contest/241642#problem/A

题意也是模板题意,很简单,错了两个地方都是小失误。。。。

一个是两个for循环索引都是i

另一个是空间没开够

略略略

#include <iostream>
#include <cstdio>
#include <string.h>
using namespace std;
const int maxn = 1100;
int id[maxn],cnt;
int qid[maxn],qcnt;
struct node
{
int to,pre;
}e[maxn];
struct node2
{
int to,ID,pre;
}q[maxn * 3];
int pre[maxn];
bool vis[maxn];
int ans[maxn];
void init(int n)
{
memset(id,-1,sizeof(id));
memset(qid,-1,sizeof(qid));
memset(vis,0,sizeof(vis));
cnt = qcnt = 0;
for(int i = 0;i <= n;i++)
pre[i] = i;
}
void add(int from,int to)
{
e[cnt].to = to;
e[cnt].pre = id[from];
id[from] = cnt++;
}
void qadd(int from,int to,int I)
{
q[qcnt].to = to;
q[qcnt].pre = qid[from];
q[qcnt].ID = I;
qid[from] = qcnt++;
}
int Find(int x)
{
if(x == pre[x])return x;
return pre[x] = Find(pre[x]);
}
void join(int u,int v)
{
int fu = Find(u),fv = Find(v);
if(fu != fv)
pre[fv] = fu;
}
void tarjan(int rt)
{ //cout<<"cs"<<" "<<rt<<endl;
for(int i = id[rt];~i;i = e[i].pre)
{
int to = e[i].to;
tarjan(to);
join(rt,to);
}
vis[rt] = 1;
for(int i = qid[rt];~i;i = q[i].pre)
{
int que = q[i].to;
if(vis[que])
{
ans[q[i].ID] = Find(que);
//cout<<Find(que)<<endl;
}
}
}
int main()
{
int t,n,m;
scanf("%d",&t);
int cas = 1;
while(t--)
{
scanf("%d",&n);
init(n);
for(int i = 1;i <= n;i++)
{
int n_num,v;
scanf("%d",&n_num);
for(int j = 0;j < n_num;++j)
{
scanf("%d",&v);
add(i,v);
}
}
scanf("%d",&m);
int u,v;
for(int i = 1;i <= m;i++)
{
scanf("%d%d",&u,&v);
qadd(u,v,i);
qadd(v,u,i);
}
tarjan(1);
printf("Case %d:\n",cas++);
for(int i = 1;i <= m;i++)
{
printf("%d\n",ans[i]);
}
}
return 0;
}

LCA tarjan+并查集POJ1470的更多相关文章

  1. hdu-2874 Connections between cities(lca+tarjan+并查集)

    题目链接: Connections between cities Time Limit: 10000/5000 MS (Java/Others)     Memory Limit: 32768/327 ...

  2. Luogu 2245 星际导航(最小生成树,最近公共祖先LCA,并查集)

    Luogu 2245 星际导航(最小生成树,最近公共祖先LCA,并查集) Description sideman做好了回到Gliese 星球的硬件准备,但是sideman的导航系统还没有完全设计好.为 ...

  3. LCA(最近公共祖先)离线算法Tarjan+并查集

    本文来自:http://www.cnblogs.com/Findxiaoxun/p/3428516.html 写得很好,一看就懂了. 在这里就复制了一份. LCA问题: 给出一棵有根树T,对于任意两个 ...

  4. POJ3694 Network - Tarjan + 并查集

    Description 给定$N$个点和 $M$条边的无向联通图, 有$Q$ 次操作, 连接两个点的边, 问每次操作后的图中有几个桥 Solution 首先Tarjan找出边双联通分量, 每个双联通分 ...

  5. BestCoder冠军赛 - 1009 Exploration 【Tarjan+并查集缩点】

    [题意] 给一个图,这个图中既有有向边,又有无向边,每条边只能走一次,问图中是否存在环. 最多10^6个点,10^6个无向边,10^6个有向边 [题解] 因为既有有向边又有无向边,所以不能单纯的用ta ...

  6. NOIP2013 D1T3 货车运输 倍增LCA OR 并查集按秩合并

    思路: Kruskal求最大生成树+倍增LCA // by SiriusRen #include <cstdio> #include <cstring> #include &l ...

  7. codeforce 505 D. Mr. Kitayuta's Technology(tarjan+并查集)

    题目链接:http://codeforces.com/contest/505/problem/D 题解:先用tarjan缩点然后再用并查集注意下面这种情况 ‘ 这种情况只需要构成一个大环就行了,也就是 ...

  8. tarjan求lca :并查集+dfs

    //参考博客 https://www.cnblogs.com/jsawz/p/6723221.html#include<bits/stdc++.h> using namespace std ...

  9. [HDOJ2586]How far away?(最近公共祖先, 离线tarjan, 并查集)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 这题以前做过…现在用tarjan搞一发…竟然比以前暴力过的慢………… 由于是离线算法,需要Que ...

随机推荐

  1. laravel 门面的介绍和使用

    #上文讲述了laravel中怎么用容器依赖注入类的示例.其实在服务提供者上面在封装一层静态调用,这就是门面.静态调用门面,返回了容器中注册的别名和实例. #下面是测试的示例 #先创建要操作的类 < ...

  2. BZOJ1217或洛谷2279 [HNOI2003]消防局的设立

    BZOJ原题链接 洛谷原题链接 该题有两种做法,树形\(DP\)和贪心. 先讲贪心. 先将所有点按深度从大到小排序,然后从大到小依次取出点,若已经被覆盖则跳过,否则就在它的祖父点建立消防站. 考虑如何 ...

  3. iOS 3D Touch功能

    新的触摸体验——iOS9的3D Touch 一.引言 在iphone6s问世之后,很多果粉都争先要体验3D Touch给用户带来的额外维度上的交互,这个设计之所以叫做3D Touch,其原理上是增加了 ...

  4. 说说为什么会有ssl.CertificateError报错

    有一些网站没有获取浏览器的颁发的安全证书 当你在请求这个网站时浏览器会当做不安全网站处理 因此会报ssl.CertificateError 解决办法是 :将默认的证书验证模式修改为不需要验证 代码如下 ...

  5. 1.3 Java中的标识符和关键字

    1.标识符 含义:标识符用于给程序中的类.变量.方法命名的符号. 组成:数字(0-9).字母(a-z)(A-Z).下划线(_).美元符号$. 命名规则:1.数字不能够作为命名符号的开头 2.不能够使用 ...

  6. ui设计学习路线图分享送给初学者

    本文来源:千锋UI设计 Ui设计师就业市场前景及薪资很可观,而且现在市场上对于ui设计师的人才需求也很大,所以,现在越来越多的人看好这一行业,纷纷投入到ui设计的学习中来,那么想新手想要学好ui设计, ...

  7. MySQL单行注释和多行释

    单行注释:# 或者 -- 多行注释:/* ... */ 使用 # 时,# 和注释的内容之间可以没有空格 使用 -- 时,-- 和注释内容之间必须有空格

  8. javase高级技术 - 泛型

    在写案例之前,先简单回顾下泛型的知识 我们知道,java属于强变量语言,使用变量之前要定义,并且定义一个变量时必须要指明它的数据类型,什么样的数据类型赋给什么样的值. 所谓“泛型”,就是“宽泛的数据类 ...

  9. Oracle 12c的可插拔数据库PDB

    1. 默认安装之后会有一个可插拔数据库:pdborcl 2. 启动根容器: [oracle@eric ~]$ export ORACLE_SID=orcl [oracle@eric ~]$ sqlpl ...

  10. [ASP.NET]使用Oracle.ManagedDataAccess的OracleParameter参数化和OracleDataAdapter模糊查询

    今天写个查询员工的信息的demo遇到了2个问题 问题1.使用Oracle.ManagedDataAccess的OracleParameter参数化 OracleParameter 的使用(参数名要以: ...