zoukankan      html  css  js  c++  java
  • 2.8 Treepath 题解

    2.8

    Treepath

    链接:https://ac.nowcoder.com/acm/problem/14248
    题解:给一颗树,求无序的偶长度路径数量

    对于每一个节点,考虑两种路径

    1.当前节点到子节点的路径

    只需要预处理出\(t[i]\)\(k[i]\),分别表示当前节点到子节点的偶路径数和奇路径数(为了方便统计,包含自己,计算时减去就行了),每到一个节点将\(t[i]++\),并把子节点的奇路径数加到偶路径数,偶路径数加到奇路径数(因为长度为1,会改变奇偶),统计就不用说了。

    2.不同子树的子节点经过当前节点的路径

    不同子树的子节点经过当前节点的路径为偶只有两种情况:到当前节点的路径长度同奇或同偶。

    所以每统计一个子树,就更新奇路径节点和偶路径节点的个数,按统计子树的每个奇节点和偶节点与前面子树分别匹配就完了。

    时间复杂度:\(O(n)\)

    Code

    #include <bits/stdc++.h>
    using namespace std;
    #define R
    typedef long long ll;
    const int MAXN = 5e5 + 5;
    int Last[MAXN],End[MAXN],Next[MAXN],cnt;
    ll k[MAXN],t[MAXN];
    void add(int x,int y)
    {
    	End[++cnt] = y;Next[cnt] = Last[x];Last[x] = cnt;
    }
    void dfs1(int x,int fa)
    {
    	t[x] = 1;
    	for(R int i = Last[x];i; i = Next[i])
    	{
    		int y = End[i];
    		if(y != fa)
    		{
    			dfs1(y,x);
    			k[x] += t[y];
    			t[x] += k[y];
    		}
    	}
    }
    ll ans;
    void dfs2(int x,int fa)
    {
    	int kk = 0,tt = 0;
    	ans += t[x] - 1;
    	for(R int i = Last[x];i; i = Next[i])
    	{
    		int y = End[i];
    		if(y != fa)
    		{
    			ans += k[y] * kk + t[y] * tt ;
    			kk += k[y];
    			tt += t[y];
    			dfs2(y,x);
    		}
    	}
    }
    int main()
    {
    	int n;
    	scanf("%d", &n);
    	for(R int i = 1;i < n; i++)
    	{
    		int x,y;
    		scanf("%d %d", &x, &y);
    		add(x,y);
    		add(y,x);
    	}
    	dfs1(1,0);
    	dfs2(1,0);
    	printf("%lld", ans); 
    	return 0;
    }
    
  • 相关阅读:
    数字图像处理领域就业前景
    opencv 学习方法
    学习opencv tutorials
    win64+VS2010+OPENCV2.4.9配置问题
    libsvm使用步骤
    生成libSVM的数据格式及使用方法
    一堆应该记住的概念
    static静态变量的理解
    C程第一节课
    扫雷但是不会恭喜
  • 原文地址:https://www.cnblogs.com/XuKeQAQ/p/14393436.html
Copyright © 2011-2022 走看看