寻找克尔苏加德

T3.寻找克尔苏加德search.cpp/pas/in/out

  四人小分队终于来到了纳克萨玛斯最后一层,在这里,克尔苏加德的的王座上,留着……一张纸条。正当铜须要拿起纸条,突然,一道淡蓝色光芒飘入了他的眼中……

  我是克尔苏加德,人类,来到我的城堡就要接受我的审判,来找我吧,卑微的蝼蚁!铜须如是说。

雷诺.杰克逊:这家伙竟然控制了我们的同伴!不过在它变成死灵法师之前,不也是一个人类吗,真是嘲讽。

克尔苏加德:早就不是了!这卑微的种族!我现在可是亡灵天灾的首席法师——克尔苏加德!

芬利.莫格顿:%^&##@#%^(自行脑补)

克尔苏加德:问得好,你这恶心的鱼人!我给你们点提示吧,省得我等太长时间才能杀掉你们。但是,我要把你们分散开~~~

题目描述:

  四人现在位于一个类似于树的迷宫里(树的根为一),被克尔苏加德分成了两组,根据线索,两组人要先会合汇合点为这两组人之间最短路上深度最小的点(设为点A),然而克尔苏加德会在点A与其在树上最远点的中点出现。如果中间点有两个,则他会一分为二,现在,去找到他,救出铜须,找到魔法书!

数据输入:

第一行,数字n,代表树的节点数。

2~n行每行两个数,表示两点之间有边相连

n+1行,两个数字,表示两组人所在节点。

数据输出:

一个(或两个)数,代表克尔苏加德的位置。

输入样例1:

13

1 2

1 3

2 4

2 5

4 6

4 7

4 8

3 9

7 10

8 11

9 12

9 13

10 11

输出样例1:

1 3

输入样例2:

13

1 2

1 3

2 4

2 5

4 6

4 7

4 8

3 9

7 10

8 11

9 12

9 13

10 5

输出样例2:

   3

数据范围

   0<n<=20000

P.S.如果有多个距A距离最大的点,则取字典序最小值的那一个。

 

老爷子第3题,几乎是裸的lca,找到lcabfs,记录父亲,再往回找即可。

 

#include<bits/stdc++.h>
#define M 50010
#define mi 21
using namespace std;

int n,m,zy=99999999,f[M][mi],deep[M],d[20010],MAX,dad[20010];
bool went[20010];

void in(int &x)
{
    char c=getchar();x=0;
    while(c<'0'||c>'9')c=getchar();
    while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();
}
struct node
{
    int n;
    node *next;
}*e[M];

void push(int x,int y)
{
    node *p;
    p=new node();
    p->n=y;
    if(e[x]==NULL)
     e[x]=p;
    else
    {
        p->next=e[x]->next;
        e[x]->next=p;
    }
}

void build(int now)
{
    deep[now]=deep[f[now][0]]+1;
    for(int i=1;(1<<i)<=deep[now];i++) f[now][i]=f[f[now][i-1]][i-1];
    for(node *i=e[now];i!=NULL;i=i->next)
      if(i->n!=f[now][0])
      {
          f[i->n][0]=now;
          build(i->n);
      }
}

int query(int x,int y)
{
    if(deep[x]<deep[y])
    swap(x,y);
    int c=deep[x]-deep[y];
    for(int i=0;(1<<i)<=c;i++)
     if((1<<i)&c)
      x=f[x][i];
    if(x==y)
    return x;
    for(int i=log2(deep[x]);i>=0;i--)
    {
        if(f[x][i]!=f[y][i])
        {
            x=f[x][i];
            y=f[y][i];
        }
    }
    return f[x][0];
}

queue<int>q;

void bfs(int x)
{
    q.push(x);
    node *p;
    while(!q.empty())
    {
        p=e[q.front()];
        went[q.front()]=true;
        while(p!=NULL)
        {
            if(!went[p->n])
            {
                dad[p->n]=q.front();
              d[p->n]=d[q.front()]+1;    
              q.push(p->n);
              if(d[p->n]>=MAX)
                  MAX=d[p->n];
              
            }
            p=p->next;
        }
        q.pop();
    }
}

int main()
{
    freopen("search.in","r",stdin);
    freopen("search.out","w",stdout);
   in(n);
   int x,y;
   for(int i=1;i<n;i++)
     {
         in(x),in(y);
         push(x,y);
         push(y,x);
     }
    build(1);
    in(x),in(y);
    int lca=query(x,y);
    bfs(lca);
    for(int i=1;i<=n;i++)
    if(d[i]==MAX)
     zy=min(zy,i);
    int dd=zy;
    while(dd!=lca)
    {
        if(d[dd]==MAX/2)
        {
            cout<<dd<<endl;
            break;
        }
        if((d[dd]==MAX/2+1)&&MAX%2!=0)
        {
            int tt=dad[dd];
            cout<<min(tt,dd)<<' ';
            cout<<max(tt,dd)<<endl;
            break;
        }
        dd=dad[dd];
    }
   return 0;
}

 

posted @ 2017-08-15 11:01  WeiAR  阅读(196)  评论(0编辑  收藏  举报