题意:树中长度路径为偶数的路径数,不能重复
分析:
首先 树中点x到点y的距离 =dep[x]+dep[y]-2*dep[LCA(x,y)]
首先可以发现,2*dep[LCA(x,y)]对奇偶性无影响
那么就剩下dep[x]和dep[y]
所以我们只需要求出深度为奇数的个数和偶数的个数
然后奇偶性相同的两两组合就是一种情况
深度为奇数个数:a
深度为偶数个数:b
答案=a(a-1)/2+b(b-1)/2
code
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <queue>
#include <deque>
#include <set>
#include <stack>
#include <cctype>
#include <cmath>
#include <cassert>
using namespace std;
typedef long long ll;
const ll mod=1000000007;
ll powmod(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
const int N=100000+100;
int head[N],tot;
int dep[N];
int n;
int x,y;
int f[N];
struct Edge
{
int e;
int to;
}edge[N<<1];
void add_edge(int u,int v)
{
tot++;
edge[tot].e=v;
edge[tot].to=head[u];
head[u]=tot;
}
void dfs(int u,int fa)
{
for(int i=head[u];i!=0;i=edge[i].to)
{
int v=edge[i].e;
if(v==fa)continue;
dep[v]=dep[u]+1;
dfs(v,u);
}
}
int main()
{
scanf("%d",&n);
for(int i=0;i<n-1;i++)
{
scanf("%d%d",&x,&y);
add_edge(x,y);
add_edge(y,x);
}
dfs(1,0);
// for(int i=1;i<=n;i++)
// {
// printf("节点%d的深度为%d\n",i,dep[i]);
// }
int s1=0;
int s2=0;
for(int i=1;i<=n;i++)
{
if(dep[i]%2==0)
{
s1++;
}
else
{
s2++;
}
}
ll ans=1ll*(s1*1ll-1)*s1*1ll/2+1ll*(s2*1ll-1)*s2*1ll/2;
printf("%lld\n",ans);
return 0;
}

京公网安备 11010502036488号