BZOJ 1787 Ahoi2008 Meet紧急集合

1787: [Ahoi2008]Meet 紧急集合

Time Limit: 20 Sec  Memory Limit: 162 MB
Submit: 3590  Solved: 1642
[Submit][Status][Discuss]

Description

Input

Output

Sample Input

6 4
1 2
2 3
2 4
4 5
5 6
4 5 6
6 3 1
2 4 4
6 6 6

Sample Output


5 2
2 5
4 1
6 0

HINT

Source

设自己在x点,小可可在y点,小可可的朋友在z点,那么设xy为x和y的lca,xz为x和z的lca,yz为y和z的lca

那么汇聚点要么在xy要么在yz要么在xz

三个进行比较即可

代码如下

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 inline int read()
  4 {
  5  int x=0;int f=1;char ch=getchar();
  6  while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
  7  while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
  8  return x*f;
  9 }
 10 const int MAXN=1e6+10;
 11 int fa[MAXN][25],linkk[MAXN*2],depth[MAXN],len,n,m;
 12 struct node
 13 {
 14  int y,next;
 15 }e[MAXN*2];
 16 inline void insert(int xx,int yy)
 17 {
 18  e[++len].y=yy;e[len].next=linkk[xx];linkk[xx]=len;
 19 }
 20 void dfs(int father,int st,int dep)
 21 {
 22  fa[st][0]=father;depth[st]=dep;
 23  for(int i=linkk[st];i;i=e[i].next)
 24  {
 25   if(e[i].y!=father) dfs(st,e[i].y,dep+1);
 26  }
 27 }
 28 void getfather()
 29 {
 30   for(int i=1;i<=20;i++)
 31   {
 32    for(int j=1;j<=n;j++)
 33    {
 34     if(fa[j][i-1]!=0) fa[j][i]=fa[fa[j][i-1]][i-1];
 35    }
 36   }
 37 }
 38 int LCA(int x,int y)
 39 {
 40  if(x==y) return x;
 41  if(depth[x]<depth[y]) swap(x,y);
 42  for(int i=20;i>=0;i--)
 43  {
 44   if(depth[x]-(1<<i)>=depth[y]) x=fa[x][i];
 45  }
 46  if(x==y) return x;
 47  for(int i=20;i>=0;i--)
 48  {
 49   if(fa[x][i]!=fa[y][i]) {x=fa[x][i];y=fa[y][i];}
 50  }
 51  return fa[x][0];
 52 }
 53 void find()
 54 {
 55  int xx=read();int yy=read();int zz=read();
 56  int xy=LCA(xx,yy);int xz=LCA(xx,zz);int yz=LCA(yy,zz);
 57  //cout<<xy<<' '<<xz<<' '<<yz<<endl;
 58  int ans1;int ans2=10000000;
 59  int xyz=LCA(xy,zz);
 60  if(depth[xx]+depth[yy]-depth[xy]-depth[xyz]*2+depth[zz]<ans2)
 61  {
 62   ans2=depth[xx]+depth[yy]-depth[xy]-depth[xyz]*2+depth[zz];
 63   ans1=xy;
 64  }
 65  xyz=LCA(xz,yy);
 66  if(depth[xx]+depth[zz]-depth[xz]-depth[xyz]*2+depth[yy]<ans2)
 67  {
 68   ans2=depth[xx]+depth[zz]-depth[xz]-depth[xyz]*2+depth[yy];
 69   ans1=xz;
 70  }
 71  xyz=LCA(yz,xx);
 72  if(depth[yy]+depth[zz]-depth[yz]-depth[xyz]*2+depth[xx]<ans2)
 73  {
 74   ans2=depth[yy]+depth[zz]-depth[yz]-depth[xyz]*2+depth[xx];
 75   ans1=yz;
 76  }
 77  printf("%d %d\n",ans1,ans2);
 78 }
 79 void init()
 80 {
 81  n=read();m=read();
 82  len=0;
 83  for(int i=1;i<n;i++)
 84  {
 85   int xx=read();
 86   int yy=read();
 87   insert(xx,yy);
 88   insert(yy,xx);
 89  }
 90  dfs(0,1,1);
 91  getfather();
 92  for(int i=1;i<=m;i++)
 93  {
 94   find();
 95  }
 96 }
 97 int main()
 98 {
 99  init();
100  return 0;
101 }
posted @ 2017-11-05 15:59  zhangenming  阅读(76)  评论(0编辑  收藏  举报