首页 > 代码库 > CodeForces 29D Ant on the Tree

CodeForces 29D Ant on the Tree

给一颗树,1为根,要求遍历树上所有点,给出叶子结点的访问顺序,限制每条边至多访问两次。


首先这是一棵树,那么两点之间的路线是确定的,所以我第一遍dfs预处理出从根节点到每个叶子的路径保存,以便后面输出。

那么就按照题目要求输出叶子结点的顺序依次输出,然后从一个叶子到下一个叶子的时候,从他们的最近公共祖先转折,所以我还预处理了相邻两个叶子结点的LCA。


#include <iostream>
#include <cstdlib>
#include <cstring>
#include <string>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
#define inf 0x3f3f3f3f
#pragma comment(linker, "/STACK:16777216")
#define eps 1e-6
#define ll long long
using namespace std;

const int maxn=310;
struct node
{
    int v,id,w;//id为边号或询问号
    node* next;
}ed[maxn<<2],*head[maxn],*q[maxn];

struct qnode
{
    int u,v,ans;//存询问结点,ans最近公共祖先
} qu[maxn];

int fa[maxn],vis[maxn],cnt;

void init(int n)
{
    cnt=0;
    memset(vis,0,sizeof vis);
    memset(head,0,sizeof head);
    memset(q,0,sizeof q);
    for(int i=0;i<=n;i++)
        fa[i]=i;
}

int getfa(int x)
{
    if(fa[x]==x) return x;
    return fa[x]=getfa(fa[x]);
}

void LCA(int u)
{
    fa[u]=u,vis[u]=1;
    for(node *p=q[u];p!=NULL;p=p->next)
    {
        if(vis[p->v])
        {
            int id=p->id;
            qu[id].ans=getfa(p->v);
        }
    }
    for(node *p=head[u];p!=NULL;p=p->next)
    {
        if(!vis[p->v])
        {
            LCA(p->v);
            fa[p->v]=u;
        }
    }
}

void adde(node *e[],int u,int v,int w,int id)//建边e传头节点数组。为询问边的或树边的。
{
    ed[cnt].v=v;
    ed[cnt].w=w;
    ed[cnt].id=id;
    ed[cnt].next=e[u];
    e[u]=&ed[cnt++];
}

inline int ReadInt()
{
    char ch = getchar();
    if (ch==EOF) return -1;
    int data = http://www.mamicode.com/0;>