寻找克尔苏加德
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,找到lca后bfs,记录父亲,再往回找即可。
#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; }