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;
}

  

posted @ 2012-05-01 16:07  快乐.  阅读(195)  评论(0编辑  收藏  举报