bzoj1787
lca裸題,畫畫圖看看就可以了,找出那個一次公共祖先,求距離
#include<iostream> #include<set> #include<cstring> #include<algorithm> #include<cmath> #include<cstdio> #include<vector> using namespace std; int n,m,u,v,a,b,c,ans,temp1; int used[1000010],dis[1000010],dep[1000010]; int acs[1000010][23]; vector<int>graph[1000010]; void dfs(int u,int d) {used[u]=1;dep[u]=d;for(int i=0;i<graph[u].size();i++){int v=graph[u][i];if(!used[v]){acs[v][0]=u;dfs(v,d+1);}} } void get_acs() { for(int j=1;j<=22;j++)for(int i=1;i<=n;i++)if(acs[i][j-1]<0)acs[i][j]=-1;elseacs[i][j]=acs[acs[i][j-1]][j-1]; } int lca(int x,int y) { if(dep[x]<dep[y])swap(x,y);int d=dep[x]-dep[y];for(int k=22;k>=0;k--)if(acs[x][k]!=-1&&(d&(1<<k)))x=acs[x][k];if(x==y)return x;for(int k=22;k>=0;k--)if(acs[x][k]>0&&acs[y][k]>0&&acs[x][k]!=acs[y][k]){x=acs[x][k];y=acs[y][k];}return acs[x][0]; } inline int calc(int x,int y) {int temp=lca(x,y);return abs(dep[x]-dep[temp])+abs(dep[y]-dep[temp]); } int main() {cin>>n>>m;for(int i=1;i<n;i++){scanf("%d%d",&u,&v);graph[u].push_back(v);graph[v].push_back(u);} memset(acs,-1,sizeof(acs));dfs(1,1);get_acs(); // cout<<endl;for(int i=1;i<=m;i++){scanf("%d%d%d",&a,&b,&c);int x=lca(a,b);int y=lca(b,c);int z=lca(c,a);if(x==y)temp1=z;elseif(y==z)temp1=x;elseif(x==z)temp1=y;ans=calc(a,temp1)+calc(b,temp1)+calc(c,temp1);printf("%d %d\n",temp1,ans); }return 0; }?
轉載于:https://www.cnblogs.com/19992147orz/p/6034481.html
總結
- 上一篇: BEM
- 下一篇: bindService初步了解