POJ 1330 Nearest Common Ancestors&&POJ1470 Closest Common Ancestors最近公共祖先 LCA
poj 1330 http://poj.org/problem?id=1330
最基础的了吧
代码:
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#define nMAX 10005
using namespace std;
int head[nMAX],parent[nMAX];
bool vs[nMAX],use[nMAX],fg;
int s_edge,n,start,end;
struct Edge
{
int v,nxt;
}edge[nMAX];
void addedge(int u,int v)
{
edge[++s_edge].v=v;
edge[s_edge].nxt=head[u];
head[u]=s_edge;
}
//递归找根节点
int find(int u)
{
if(parent[u]==-1)return u;
return parent[u]=find(parent[u]);
}
//tarjan
void tarjan(int u)
{
if(fg)return ;
vs[u]=1;
if(u==end&&vs[start]==1)
{printf("%d\n",find(start));
fg=1; return ;}
if(u==start&&vs[end]==1)
{printf("%d\n",find(end));
fg=1; return ;}
for(int e=head[u];e;e=edge[e].nxt)
{
int v=edge[e].v;
if(!vs[v])
{
tarjan(v);
parent[v]=u;
}
}
}
void init()
{
memset(head,0,sizeof(head));
memset(parent,-1,sizeof(parent));
memset(vs,0,sizeof(vs));
memset(use,0,sizeof(use));
s_edge=0;
fg=0;
}
int main()
{
int CASE,i,j,k;
scanf("%d",&CASE);
while(CASE--)
{
init();
scanf("%d",&n);
for(k=1;k<n;k++)
{
scanf("%d%d",&i,&j);
addedge(i,j);
use[j]=1;
}
scanf("%d%d",&start,&end);
for(i=1;i<=n;i++)
if(!use[i])break;
tarjan(i);
}
return 0;
}
POJ 1470
http://poj.org/problem?id=1470
输入和存储得注意
代码:
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#define nMAX 905
using namespace std;
int head1[nMAX],head2[nMAX],parent[nMAX],ans[nMAX*nMAX],ret[nMAX];
bool vs[nMAX],use[nMAX];
int s_edge1,s_edge2,n;
struct Edge1
{
int v,nxt;
}edge1[nMAX*nMAX];
struct Edge2
{
int v,w,nxt;
}edge2[nMAX*nMAX];
void addedge1(int u,int v)
{
edge1[++s_edge1].v=v;
edge1[s_edge1].nxt=head1[u];
head1[u]=s_edge1;
}
void addedge2(int u,int v,int w)
{
edge2[++s_edge2].v=v;
edge2[s_edge2].w=w;
edge2[s_edge2].nxt=head2[u];
head2[u]=s_edge2;
edge2[++s_edge2].v=u;
edge2[s_edge2].w=w;
edge2[s_edge2].nxt=head2[v];
head2[v]=s_edge2;
}
void init()
{
memset(vs,0,sizeof(vs));
memset(use,0,sizeof(use));
memset(parent,-1,sizeof(parent));//初始化为-1
memset(head1,0,sizeof(head1));
memset(head2,0,sizeof(head2));
s_edge1=0;
s_edge2=0;
}
int find(int u)
{
if(parent[u]==-1)return u;
return parent[u]=find(parent[u]);
}
void tarjan(int u)
{
int i,v,w,e;
vs[u]=1;
for(e=head2[u];e;e=edge2[e].nxt)
{
v=edge2[e].v;
w=edge2[e].w;
if(vs[v])
{
ans[w]=find(v);
}
}
for(e=head1[u];e;e=edge1[e].nxt)
{
v=edge1[e].v;
if(!vs[v])
{
tarjan(v);
parent[v]=u;
}
}
}
int main()
{
int i,j,cnt,k,m;
while(~scanf("%d",&n))
{
init();
for(i=1;i<=n;i++)
{
scanf("%d:(%d)",&j,&cnt);
while(cnt--)
{
scanf("%d",&k);
addedge1(j,k);
use[k]=1;//不是根节点
}
}
scanf("%d",&m);
for(k=1;k<=m;k++)
{
scanf(" (%d %d)", &i, &j);
//开始scanf("(%d %d)", &x, &y) 怎么输怎么错呀!!!
addedge2(i,j,k);
}
for(i=1;i<=n;i++)//找根节点
if(!use[i])break;
tarjan(i);
sort(ans+1,ans+m+1);
memset(ret,0,sizeof(ret));
for(i=1;i<=m;i++)
ret[ans[i]]++;
for(i=1;i<=n;i++)
if(ret[i]!=0)printf("%d:%d\n",i,ret[i]);
}
return 0;
}

浙公网安备 33010602011771号