zoukankan      html  css  js  c++  java
  • Codeforces 519E A and B and Lecture Rooms|LCA

    题目链接

    大意:给定两个点,求树中有多少点到这两个点的距离相等。两点间的距离指两点之间的最短路的边数。多组询问

    LCA好题

    思路:跑LCA然后暴力讨论

    1.两点相等

    显然整棵树都是答案

    2.两点与(LCA) 的距离相等

    那么,除(LCA)上这两个点所属的子树外,其余的点都是答案

    3.两点与(LCA)的距离不相等

    这里有点复杂。

    首先,如果两点与(LCA)的距离和为奇数,则无解。

    如果是偶数,则两点到(LCA)的路径上,必然有一个点的到两点间的距离相同,其子树上的所有点(除包含所询问点的子树外),距离也会相同。

    那么,我们可以从深度较大的询问点出发,跳到该点后,求出子树的大小,再减去包含询问点的子树就行了。

    #include<bits/stdc++.h>
    using namespace std;
    int cc,to[200100],net[200100],fr[200100],n,a,b,m,x,y;
    int f[100100][20],fa[100100],dep[100100],siz[100100];
    void addedge(int u,int v)
    {
    	cc++;
    	to[cc]=v;net[cc]=fr[u];fr[u]=cc;
    }
    void dfs(int x)
    {
    	siz[x]=1;
    	for (int i=1;i<=19;i++)
    	  f[x][i]=f[f[x][i-1]][i-1];
    	for (int i=fr[x];i;i=net[i])
    	{
    		int y=to[i];
    		if (y==f[x][0]) continue;
    		f[y][0]=x;dep[y]=dep[x]+1;
    		dfs(y);
    		siz[x]+=siz[y];
    	}
    	return ;
    }
    void Lca(int x,int y)
    {
    	int yx=x,yy=y;
    	if (dep[x]>dep[y]) swap(x,y);
    	for (int i=19;i>=0;i--)
    	  if (dep[f[y][i]]>=dep[x]) y=f[y][i];
    	for (int i=19;i>=0;i--)
    		if (f[x][i]!=f[y][i])
    		{
    			x=f[x][i];y=f[y][i];
    		}
        //LCA
    	if (f[x][0]==f[y][0]) 
    	{
    		int fa=0;
    		if (x==y) fa=x;else fa=f[x][0];
    		if (dep[fa]-dep[yx]==dep[fa]-dep[yy])
    		{
    			if (yx==yy) cout<<n<<endl;else cout<<n-siz[x]-siz[y]<<endl;//情况1.2
    		}
    		else
    	    {
    	    	if ((dep[fa]-dep[yx]+dep[fa]-dep[yy])%2) cout<<"0
    ";else 
    			{
    				int b=(dep[yx]-dep[fa]-dep[fa]+dep[yy])/2 -1;//-1是因为方便减去不合法的节点
    			   if (dep[yx]>dep[yy]) swap(yx,yy);
    			   for (int i=19;i>=0;i--)
    			   {
    			   	  if ((b>>i)&1)
    			   	  	 yy=f[yy][i];
    			   }//跳到此节点
    			   cout<<siz[f[yy][0]]-siz[yy]<<endl;
    		    }
    	    }
    	}
    	else {cout<<0<<endl;return ;}
    }
    int main()
    {
    	cin>>n;
    	for (int i=1;i<n;i++)
    	{
    	  cin>>a>>b;
    	  addedge(a,b);
    	  addedge(b,a);
        }
        dep[1]=1;
        dfs(1);
        cin>>m;
        for (int i=1;i<=m;i++)
        {
        	cin>>x>>y;
        	Lca(x,y);
        }
    	return  0;
    }
    
    
  • 相关阅读:
    matplotlib 进阶之origin and extent in imshow
    Momentum and NAG
    matplotlib 进阶之Tight Layout guide
    matplotlib 进阶之Constrained Layout Guide
    matplotlib 进阶之Customizing Figure Layouts Using GridSpec and Other Functions
    matplotlb 进阶之Styling with cycler
    matplotlib 进阶之Legend guide
    Django Admin Cookbook-10如何启用对计算字段的过滤
    Django Admin Cookbook-9如何启用对计算字段的排序
    Django Admin Cookbook-8如何在Django admin中优化查询
  • 原文地址:https://www.cnblogs.com/fmj123/p/CF519E.html
Copyright © 2011-2022 走看看