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;
    }
    
  • 相关阅读:
    HDU5418.Victor and World(状压DP)
    POJ2686 Traveling by Stagecoach(状压DP)
    POJ3254Corn Fields(状压DP)
    HDU5407.CRB and Candies(数论)
    CodeForces 352D. Jeff and Furik
    CodeForces 352C. Jeff and Rounding(贪心)
    LightOj 1282 Leading and Trailing
    Ural 1057. Amount of Degrees(数位DP)
    HDU 2089 不要62 (数位DP)
    HDU5366 The mook jong (DP)
  • 原文地址:https://www.cnblogs.com/lokiii/p/9646235.html
Copyright © 2011-2022 走看看