题意:树中长度路径为偶数的路径数,不能重复

分析:

首先 树中点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;
}