首页 > 其他 > 详细

2.8 Treepath 题解

时间:2021-02-09 18:11:51      阅读:33      评论:0      收藏:0      [点我收藏+]

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;
}

2.8 Treepath 题解

原文:https://www.cnblogs.com/XuKeQAQ/p/14393436.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!