zoukankan      html  css  js  c++  java
  • bzoj 1787: [Ahoi2008]Meet 紧急集合【树链剖分lca】

    对于三个点求最小路径长度和,答案肯定在某两个点的lca上,因为如果把集合点定在公共lca上,一定有两个点汇合后再一起上到lca,这样显然不如让剩下的那个点下来
    这个lca可能是深度最深的……但是我懒得证了,反正只有三个lca,每个都求一遍然后取个max就好啦

    #include<iostream>
    #include<cstdio>
    using namespace std;
    const int N=500005;
    int n,m,h[N],cnt,de[N],si[N],fa[N],hs[N],fr[N];
    struct qwe
    {
    	int ne,to;
    }e[N<<1];
    int read()
    {
    	int r=0,f=1;
    	char p=getchar();
    	while(p>'9'||p<'0')
    	{
    		if(p=='-')
    			f=-1;
    		p=getchar();
    	}
    	while(p>='0'&&p<='9')
    	{
    		r=r*10+p-48;
    		p=getchar();
    	}
    	return r*f;
    }
    void add(int u,int v)
    {
    	cnt++;
    	e[cnt].ne=h[u];
    	e[cnt].to=v;
    	h[u]=cnt;
    }
    void dfs1(int u,int fat)
    {
        fa[u]=fat;
        de[u]=de[fat]+1;
        si[u]=1;
        for(int i=h[u];i;i=e[i].ne)
            if(e[i].to!=fat)
            {
                dfs1(e[i].to,u);
                si[u]+=si[e[i].to];
                if(si[e[i].to]>si[hs[u]])
                    hs[u]=e[i].to;
            }
    }
    void dfs2(int u,int top)
    {
        fr[u]=top;
        if(!hs[u])
            return;
        dfs2(hs[u],top);
        for(int i=h[u];i;i=e[i].ne)
            if(e[i].to!=fa[u]&&e[i].to!=hs[u])
                dfs2(e[i].to,e[i].to);
    }
    int lca(int u,int v)
    {//cerr<<u<<"    "<<v<<endl;
        for(;fr[u]!=fr[v];de[fr[u]]>de[fr[v]]?u=fa[fr[u]]:v=fa[fr[v]]);
        return de[u]<de[v]?u:v;
    }
    int main()
    {
    	n=read(),m=read();
    	for(int i=1;i<n;i++)
    	{
    		int x=read(),y=read();
    		add(x,y),add(y,x);
    	}
    	dfs1(1,0);
    	dfs2(1,1);
    	while(m--)
    	{
    		int x=read(),y=read(),z=read(),lc1=lca(x,y),lc2=lca(y,z),lc3=lca(z,x),lc,ans=1e9,p,nw;//cerr<<x<<" "<<y<<" "<<z<<endl;
    		lc=lca(lc1,z);//cerr<<lc<<endl;
    		nw=de[x]-de[lc1]+de[y]-de[lc1]+de[z]-de[lc]+de[lc1]-de[lc];
    		if(nw<ans)
    			ans=nw,p=lc1;
    		lc=lca(lc2,x);//cerr<<lc<<endl;
    		nw=de[y]-de[lc2]+de[z]-de[lc2]+de[x]-de[lc]+de[lc2]-de[lc];
    		if(nw<ans)
    			ans=nw,p=lc2;
    		lc=lca(lc3,y);//cerr<<lc<<endl;
    		nw=de[z]-de[lc3]+de[x]-de[lc3]+de[y]-de[lc]+de[lc3]-de[lc];
    		if(nw<ans)
    			ans=nw,p=lc3;
    		printf("%d %d
    ",p,ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    记一次 .NET 某智能服装智造系统 内存泄漏分析
    记一次 .NET 某化妆品 webapi 卡死分析
    记一次 .NET 某公交卡扣费系统 程序卡死分析
    去掉烦人的:要恢复页面吗?Chrome未正确关闭
    C#Excel转图片代码
    ArcEngine实现pagelayout中文本元素的属性对话框
    arcgis 模型版本问题最大
    Arcengine开发所遇错误解决方案(持续更新)
    ArcEngine IPageLayout 添加经纬网和公里网
    Arcengine的复制粘贴
  • 原文地址:https://www.cnblogs.com/lokiii/p/9646235.html
Copyright © 2011-2022 走看看