zoukankan      html  css  js  c++  java
  • 2478. [HZOI 2016]简单的最近公共祖先

    ★☆   输入文件:easy_LCA.in   输出文件:easy_LCA.out   简单对比

    时间限制:2 s   内存限制:128 MB

    【题目描述】

    给定一棵有n个节点的有根树,根节点为1,每个节点有一个权值wi,求

    即求所有无序节点对的LCA的权值之和。

    树的节点编号为1~n,LCA表示两节点的最近公共祖先,即在它们的所有公共祖先中离根节点最远的节点。

    【输入格式】

    第一行一个整数n,表示节点数。

    第二行n个正整数,表示每个点的权值。

    以下n-1行每行两个整数x,y,表示树上有一条边连接节点x和节点y。

    【输出格式】

    一个整数,表示答案。

    【样例输入】

    3
    1 2 3
    1 2
    1 3

    【样例输出】

    9

    【数据范围与约定】

    对于30%的数据,n<=1000。

    对于60%的数据,n<=100000。

    对于100%的数据,1<=n<=1000000,0<wi<=1000000。

    【来源】

    HZOI 2016

    裸地lca竟然只过3点:

    #include<iostream>
    #include<cstdio>
    
    using namespace std;
    const int N=1000010;
    
    int head[N],deep[N],w[N],jump[N][25];
    int now=1,n,root=1;
    long long answer;
    struct node{
    	int u,v,nxt;
    }E[N];
    
    inline int read()
    {
    	int x=0;char c=getchar();
    	while(c<'0'||c>'9')c=getchar();
    	while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();
    	return x;
    }
    
    inline void add(int u,int v)
    {
    	E[now].v=v;
    	E[now].nxt=head[u];
    	head[u]=now++;
    }
    
    void make_deep(int root)
    {
    	for(int i=head[root];~i;i=E[i].nxt)
    		if(!deep[E[i].v])
    			deep[E[i].v]=deep[root]+1,
    			jump[E[i].v][0]=root,
    			make_deep(E[i].v);
    }
    
    inline void make_jump()
    {
    	for(int i=1;i<=19;i++)
    		for(int j=1;j<=n;j++)
    			jump[j][i]=jump[jump[j][i-1]][i-1];
    }
    
    inline int lca(int x,int y)
    {
    	if(deep[x]<deep[y])
    		swap(x,y);
    	for(int i=19;i>=0;i--)
    		if(deep[jump[x][i]]>=deep[y])
    			x=jump[x][i];
    	if(x==y)
    		return x;
    	for(int i=19;i>=0;i--)
    		if(jump[x][i]!=jump[y][i])
    			x=jump[x][i],
    			y=jump[y][i];
    	return jump[x][0];
    }
    
    int main()
    {
    	freopen("easy_LCA4.in","r",stdin);
    	freopen("easy=_LCA.out","w",stdout);
    	n=read();
    	for(int i=1;i<=n;i++)
    		head[i]=-1,w[i]=read();
    	for(int i=1;i<n;i++)
    	{
    		int u=read(),v=read();
    		add(u,v);
    		add(v,u);
    	}
    	deep[root]=1;
    	make_deep(root);
    	make_jump();
    	
    	for(int i=1;i<=n;i++)
    		for(int j=1;j<=i;j++)
    			answer+=w[lca(i,j)];
    	
    	printf("%lld",answer);
    	return 0;
    }
    

      

    #include<cstdio>
    #include<cstring>
    
    #define Cu fclose(stdin);fclose(stdout);return 0;
    #define Begin freopen("easy_LCA.in","r",stdin);freopen("easy_LCA.out","w",stdout);chul();Cu;
    
    using namespace std;
    const int maxn=1000010;
    
    int w[maxn],head[maxn],size[maxn],tim;
    long long ans=0;
    typedef long long ll;
    int fath[maxn];
    
    struct op{
    	int to,next;
    }r[maxn<<1];
    
    void insert(int fr,int to)
    {
    	tim++;
    	r[tim].to=to;
    	r[tim].next=head[fr];
    	head[fr]=tim;
    }
    
    void dfs(int rt)
    {
    	size[rt]=1;
    	int x=0,y;
    	for(int i=head[rt];i;i=r[i].next)
    	{
    		y=r[i].to;
    		if(fath[rt]==y)continue;
    			fath[y]=rt;
    		dfs(y);
    		ans+=(ll)size[rt]*size[y]*w[rt];
    		size[rt]+=size[y];
    	}
    }
    
    void chul()
    {
    	int n,s,t;
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++)
    	{
    		scanf("%d",&w[i]);
    		ans+=w[i];
    	}
    	for(int i=1;i<n;i++)
    	{
    		scanf("%d%d",&s,&t);
    		insert(s,t);
    		insert(t,s);
    	}
    	dfs(1);
    	printf("%lld
    ",ans);
    }
    
    
    int main()
    {
    	Begin;
    }
    

      

  • 相关阅读:
    UVALive 7509 Dome and Steles
    HDU 5884 Sort
    Gym 101194H Great Cells
    HDU 5451 Best Solver
    HDU 5883 The Best Path
    HDU 5875 Function
    卡特兰数
    UVa 11729 Commando War 突击战
    UVa 11292 The Dragon of Loowater 勇者斗恶龙
    Spark Scala Flink版本对应关系
  • 原文地址:https://www.cnblogs.com/lyqlyq/p/7198747.html
Copyright © 2011-2022 走看看