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的更多相关文章
- hdu-2874 Connections between cities(lca+tarjan+并查集)
题目链接: Connections between cities Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/327 ...
- Luogu 2245 星际导航(最小生成树,最近公共祖先LCA,并查集)
Luogu 2245 星际导航(最小生成树,最近公共祖先LCA,并查集) Description sideman做好了回到Gliese 星球的硬件准备,但是sideman的导航系统还没有完全设计好.为 ...
- LCA(最近公共祖先)离线算法Tarjan+并查集
本文来自:http://www.cnblogs.com/Findxiaoxun/p/3428516.html 写得很好,一看就懂了. 在这里就复制了一份. LCA问题: 给出一棵有根树T,对于任意两个 ...
- POJ3694 Network - Tarjan + 并查集
Description 给定$N$个点和 $M$条边的无向联通图, 有$Q$ 次操作, 连接两个点的边, 问每次操作后的图中有几个桥 Solution 首先Tarjan找出边双联通分量, 每个双联通分 ...
- BestCoder冠军赛 - 1009 Exploration 【Tarjan+并查集缩点】
[题意] 给一个图,这个图中既有有向边,又有无向边,每条边只能走一次,问图中是否存在环. 最多10^6个点,10^6个无向边,10^6个有向边 [题解] 因为既有有向边又有无向边,所以不能单纯的用ta ...
- NOIP2013 D1T3 货车运输 倍增LCA OR 并查集按秩合并
思路: Kruskal求最大生成树+倍增LCA // by SiriusRen #include <cstdio> #include <cstring> #include &l ...
- codeforce 505 D. Mr. Kitayuta's Technology(tarjan+并查集)
题目链接:http://codeforces.com/contest/505/problem/D 题解:先用tarjan缩点然后再用并查集注意下面这种情况 ‘ 这种情况只需要构成一个大环就行了,也就是 ...
- tarjan求lca :并查集+dfs
//参考博客 https://www.cnblogs.com/jsawz/p/6723221.html#include<bits/stdc++.h> using namespace std ...
- [HDOJ2586]How far away?(最近公共祖先, 离线tarjan, 并查集)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 这题以前做过…现在用tarjan搞一发…竟然比以前暴力过的慢………… 由于是离线算法,需要Que ...
随机推荐
- IIS7中的站点、应用程序和虚拟目录详细介绍
IIS7中的站点.应用程序和虚拟目录详细介绍 这里说的不是如何解决路径重写或者如何配置的问题,而是阐述一下站点(site),应用程序(application)和虚拟目录 (virtual direct ...
- iOS8 UIAlertView键盘闪一下的问题
if (SYSTEM_VERSION >= 8.0) { UIAlertController *alertCtrl = [UIAlertController alertControllerWit ...
- canvas 实现烟花效果
一:创建画布 <canvas width="600" height="600" id="canvas" style="bor ...
- c#的装箱和拆箱及值类型和引用类型
装箱:它允许根据值类型创建一个对象,然后使用对这新对象的一个引用. int i = 5; object o = i; int j = (int)o; 装箱:运行时将在堆上创建一个包含值5的对象(它是一 ...
- 2019.01.10 bzoj1095: [ZJOI2007]Hide 捉迷藏(动态点分治)
传送门 蒟蒻真正意义上做的第一道动态点分治! 题意:给一棵最开始所有点都是黑点的树,支持把点的颜色变成从黑/白色变成白/黑色,问当前状态树上两个最远黑点的距离. 思路: 首先考虑不带修改一次点分治怎么 ...
- Codeforces Round #510 (Div. 2) D. Petya and Array(离散化+反向树状数组)
http://codeforces.com/contest/1042/problem/D 题意 给一个数组n个元素,求有多少个连续的子序列的和<t (1<=n<=200000,abs ...
- iphone导入照片不显示,不同步怎么整
可以借助itools或者爱思助手来处理 进入电脑软件后 找到文件管理---->文件系统(用户)这个目录 找到photodata这个文件夹,将photos.sqlite文件删除 最重要的一步来了. ...
- Oracle 导出错误 EXP-00000~EXP-00107
EXP-00000: Export terminated unsuccessfully Cause: Export encountered an Oracle error. Action: Look ...
- MySQL/Oracle视图的创建与使用
1.什么是视图? 视图是一个虚拟的表,是一个表中的数据经过某种筛选后的显示方式,视图由一个预定义的查询select语句组成. 2.视图的特点. 视图中的数据并不属于视图本身,而是属于基本的表,对视 ...
- 第36-37 Tomcat & SVN
1. Tomcat简介 tomcat是一个web服务器,类似nginx,apache的http nginx,http只能处理html等静态文件(jpg) 网页分为静态网页(以.html或者.htm结尾 ...