9 Kongs .son1 ..son1son2 ..son1son1 ...sonkson2son1 ...son1son2son2 ..son1son3 ...son1son3son1 .son0 7 L b son1son3son1 b son1son2 b sonkson2son1 b son1 c sonkson2son1 son1son2son2 c son1son3son1 son1son2 0
Kongs .son0 .son1 ..son1son1 ...son1son2son2 ...sonkson2son1 ..son1son2 ..son1son3 ...son1son3son1 1 3 2 2 son1son1 son1
有三种操作。
字典序小的先输出。
不知道有其他什么高级方法没。
然后对于操作1.因为要字典序小的的先dfs。那么仅仅好用 不是非常熟悉的vector存边了。然后对边按名字字典序排序。
然后dfs一次把答案存起来。对于2记录下一个结点的父亲是谁即可了。
对于3.tarjan离线处理。这题有个坑点就是LCA不能是自己。over。
#include<cstdio>
#include<vector>
#include<algorithm>
#include<string>
#include<cstring>
#include<iostream>
#include<map>
using namespace std;
const int maxn=30010;
int cnt,ptr,pp,vis[maxn],ty[maxn],aans[maxn];
int st[maxn],rk[maxn],fa[maxn],pa[maxn],uu[maxn],vv[maxn];
char na[100];
vector<int> G[maxn];
string name[maxn],ans[maxn];
map<string,int> mp;
struct node
{
    int v,id;
    node *next;
} ed[maxn<<1],*head[maxn];
void adde(int u,int v,int id)
{
    ed[ptr].v=v;
    ed[ptr].id=id;
    ed[ptr].next=head[u];
    head[u]=&ed[ptr++];
}
bool cmp(int a,int b)
{
    return name[a]<name[b];
}
void dfs(int u)
{
    string op=".";
    ans[pp]="";
    for(int i=0;i<rk[u];i++)
        ans[pp]+=op;
    ans[pp++]+=name[u];
    for(int i=0;i<G[u].size();i++)
    {
        pa[G[u][i]]=u;
        dfs(G[u][i]);
    }
}
int getfa(int x)
{
    if(fa[x]==x)
        return x;
    return fa[x]=getfa(fa[x]);
}
void tarjan(int u)
{
    vis[u]=1,fa[u]=u;
    for(node *p=head[u];p!=NULL;p=p->next)
    {
        if(vis[p->v])
            aans[p->id]=getfa(p->v);
    }
    for(int i=0;i<G[u].size();i++)
    {
        tarjan(G[u][i]);
        fa[G[u][i]]=u;
    }
}
int main()
{
    int i,j,n,m,tp,ct,id,u,v;
    string aa,bb;
    char cmd[20];
    while(scanf("%d",&n),n)
    {
        for(i=0;i<=n;i++)
            G[i].clear();
        mp.clear();
        tp=cnt=1;
        st[0]=0,rk[0]=-1;
        for(i=0;i<n;i++)
        {
            scanf("%s",na);
            ct=0;
            for(j=0;na[j];j++)
                if(na[j]==‘.‘)
                    ct++;
                else
                    break;
            string nna(na+ct);
            //cout<<nna<<endl;
            if(!mp.count(nna))
            {
                name[cnt]=nna;
                rk[cnt]=ct;
                mp[nna]=cnt++;
            }
            id=mp[nna];
            while(rk[st[tp-1]]>=rk[id])
                tp--;
            G[st[tp-1]].push_back(id);
            st[tp++]=id;
        }
        for(i=1;i<=n;i++)
            sort(G[i].begin(),G[i].end(),cmp);
        pp=0;
        dfs(1);
        ptr=0;
        memset(head,0,sizeof head);
        memset(vis,0,sizeof vis);
        scanf("%d",&m);
        for(i=0;i<m;i++)
        {
            scanf("%s",cmd);
            if(cmd[0]==‘L‘)
                ty[i]=0;
            else if(cmd[0]==‘b‘)
            {
                ty[i]=1;
                cin>>aa;
                id=mp[aa];
                aans[i]=G[pa[id]].size();
            }
            else
            {
                ty[i]=2;
                cin>>aa>>bb;
                u=mp[aa],v=mp[bb];
                uu[i]=u,vv[i]=v;
                adde(u,v,i);
                adde(v,u,i);
            }
        }
        tarjan(1);
        for(i=0;i<m;i++)
        {
            if(ty[i]==0)
            {
                for(j=0;j<n;j++)
                    cout<<ans[j]<<endl;
            }
            else if(ty[i]==1)
                printf("%d\n",aans[i]);
            else
            {
                if(aans[i]==uu[i]||aans[i]==vv[i])
                    aans[i]=pa[aans[i]];
                cout<<name[aans[i]]<<endl;
            }
        }
    }
    return 0;
}
hdu 4409 Family Name List(LCA&有坑点)
原文:http://www.cnblogs.com/zsychanpin/p/6859645.html