1787: [Ahoi2008]Meet 紧急集合
Time Limit: 20 Sec Memory Limit: 162 MBSubmit: 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
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 ",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 }