hdu1470Closest Common Ancestors LCA
来源:互联网 发布:管家婆数据库 编辑:程序博客网 时间:2024/06/07 18:53
//刚学lca,代码是参考大神的
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=1010;
const int maxq=500010;
int parent[maxn];
int ancestor[maxn];
int answer[maxq];
//**********************//并查集的函数
int find(int i)
{
if(parent[i]==-1)return i;
return parent[i]=find(parent[i]);
}
int join(int x,int y)
{
int x1=find(x);
int y1=find(y);
if(x1!=y1)
parent[y1]=x1;
}
//**********************//存入数的边的邻接表
int vis[maxn];
int head[maxn];
int nedge;
struct Edge
{
int to, next;
}edge[2*maxn];
void addedge(int u,int v)
{
edge[nedge].to=v;
edge[nedge].next=head[u];
head[u]=nedge++;
}
//****************************//存入询问的边的邻接表
struct Query
{
int to,next,id;
}query[2*maxq];
int nquery;
int h[maxq];
void addquery(int u,int v,int w)
{
query[nquery].to=v;
query[nquery].id=w;
query[nquery].next=h[u];
h[u]=nquery++;
}
//******************************//初始化
void init()
{
nedge = nquery = 0;
memset(parent,-1,sizeof(parent));
memset(head,-1,sizeof(head));
memset(h,-1,sizeof(head));
memset(vis,0,sizeof(vis));
memset(ancestor,0,sizeof(ancestor));
}
//*************************************
int temp;
void tarjan(int u)
{
ancestor[u]=u;
vis[u]=1;
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].to;
if(vis[v])continue;
tarjan(v);
join(u,v); //合并v到父节点u的集合,确保集合的祖先是u
ancestor[find(v)]=u;
}
for(int i = h[u];i!=-1;i=query[i].next)//处理完一个以u为根节点的子树后,这个子树的所有节点都是在一个集合中
{ //而且它们的祖先都是u
int v=query[i].to; //而对于询问中与u节点相连的节点v,
if(vis[v]) //如果在这个子树中,那么他们的公共祖先就是u,如果不是,而且在之前
answer[query[i].id]=ancestor[find(v)];//搜索过那么是原来节点所在集合的祖先
}
}
//******************************************
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int n,m;
while(scanf("%d",&n)!=EOF)
{
int num;int u;int v;int Q;
int i,j;
int flag[maxn];
init();
memset(flag,0,sizeof(flag));
for(i=1;i<=n;i++)
{
scanf("%d:(%d)",&u,&num);
while(num--)
{
scanf("%d",&v);
addedge(u,v);
//addedge(v,u);
flag[v]=1;
}
}
scanf("%d",&Q);
int a,b;
char ch;
for(j=0;j<Q;j++)
{
while(getchar()!='(');
scanf("%d %d)",&a,&b);
addquery(a,b,j);
addquery(b,a,j);
}
int root;
for(i=1;i<=n;i++)
if(!flag[i])
{
root=i;
break;
}
tarjan(root);
int count[maxn];
memset(count,0,sizeof(count));
for(i=0;i<Q;i++)
count[answer[i]]++;
for(i=1;i<=n;i++)
if(count[i])
printf("%d:%d\n",i,count[i]);
}
}
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=1010;
const int maxq=500010;
int parent[maxn];
int ancestor[maxn];
int answer[maxq];
//**********************//并查集的函数
int find(int i)
{
if(parent[i]==-1)return i;
return parent[i]=find(parent[i]);
}
int join(int x,int y)
{
int x1=find(x);
int y1=find(y);
if(x1!=y1)
parent[y1]=x1;
}
//**********************//存入数的边的邻接表
int vis[maxn];
int head[maxn];
int nedge;
struct Edge
{
int to, next;
}edge[2*maxn];
void addedge(int u,int v)
{
edge[nedge].to=v;
edge[nedge].next=head[u];
head[u]=nedge++;
}
//****************************//存入询问的边的邻接表
struct Query
{
int to,next,id;
}query[2*maxq];
int nquery;
int h[maxq];
void addquery(int u,int v,int w)
{
query[nquery].to=v;
query[nquery].id=w;
query[nquery].next=h[u];
h[u]=nquery++;
}
//******************************//初始化
void init()
{
nedge = nquery = 0;
memset(parent,-1,sizeof(parent));
memset(head,-1,sizeof(head));
memset(h,-1,sizeof(head));
memset(vis,0,sizeof(vis));
memset(ancestor,0,sizeof(ancestor));
}
//*************************************
int temp;
void tarjan(int u)
{
ancestor[u]=u;
vis[u]=1;
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].to;
if(vis[v])continue;
tarjan(v);
join(u,v); //合并v到父节点u的集合,确保集合的祖先是u
ancestor[find(v)]=u;
}
for(int i = h[u];i!=-1;i=query[i].next)//处理完一个以u为根节点的子树后,这个子树的所有节点都是在一个集合中
{ //而且它们的祖先都是u
int v=query[i].to; //而对于询问中与u节点相连的节点v,
if(vis[v]) //如果在这个子树中,那么他们的公共祖先就是u,如果不是,而且在之前
answer[query[i].id]=ancestor[find(v)];//搜索过那么是原来节点所在集合的祖先
}
}
//******************************************
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int n,m;
while(scanf("%d",&n)!=EOF)
{
int num;int u;int v;int Q;
int i,j;
int flag[maxn];
init();
memset(flag,0,sizeof(flag));
for(i=1;i<=n;i++)
{
scanf("%d:(%d)",&u,&num);
while(num--)
{
scanf("%d",&v);
addedge(u,v);
//addedge(v,u);
flag[v]=1;
}
}
scanf("%d",&Q);
int a,b;
char ch;
for(j=0;j<Q;j++)
{
while(getchar()!='(');
scanf("%d %d)",&a,&b);
addquery(a,b,j);
addquery(b,a,j);
}
int root;
for(i=1;i<=n;i++)
if(!flag[i])
{
root=i;
break;
}
tarjan(root);
int count[maxn];
memset(count,0,sizeof(count));
for(i=0;i<Q;i++)
count[answer[i]]++;
for(i=1;i<=n;i++)
if(count[i])
printf("%d:%d\n",i,count[i]);
}
}
0 0
- hdu1470Closest Common Ancestors LCA
- Nearest Common Ancestors--LCA
- 1330 Nearest Common Ancestors //LCA
- 1470 Closest Common Ancestors //LCA
- poj1330Nearest Common Ancestors(LCA小结)
- POJ1470 Closest Common Ancestors LCA
- poj1470-Closest Common Ancestors(LCA)
- Closest Common Ancestors(LCA)
- poj1470Closest Common Ancestors(LCA模版)
- poj1470Closest Common Ancestors(lca)
- POJ1330 Nearest Common Ancestors[LCA]
- 【POJ1330】Nearest Common Ancestors(LCA)
- [PKU 1330]Nearest Common Ancestors(LCA)
- poj1470——Closest Common Ancestors//LCA
- poj Nearest Common Ancestors(LCA+Tarjan)
- POJ-1330 Nearest Common Ancestors【LCA】
- POJ-1470 Closest Common Ancestors【LCA】
- POJ-1470 Closest Common Ancestors【LCA】
- Hello World
- java.lang.NoClassDefFoundError:org/hamcrest/SelfDescribing
- PAT A1010 Radix (有点问题)
- 服务器上生成和获取xml
- 15.ios之Quartz2D
- hdu1470Closest Common Ancestors LCA
- 1180 对称矩阵
- MySql的dql和dml操作的封装,成为固定的工具类
- 2015-03-09数据加载、存储与文件格式(1)
- online_judge_1206
- Comparable与Comparator的差异
- 初识Linux下C语言编程
- Jquery easyUI dialog的close和destroy
- 已知两个1~30之间的数字,甲知道两数之和,乙知道两数之积。 。。。。。