作者:Lcy榆 | 来源:互联网 | 2023-10-17 12:16
题目链接:https://ac.nowcoder.com/acm/problem/14248
来源:牛客网
题目描述
给定一棵n个点的树,问其中有多少条长度为偶数的路径。路径的长度为经过的边的条数。x到y与y到x被视为同一条路径。路径的起点与终点不能相同。
输入描述:
第一行一个数n表示点的个数&#xff1b;接下来n-1行&#xff0c;每行两个整数x&#xff0c;y表示边&#xff1b;保证输入数据形成一棵树&#xff1b;1<&#61;n<&#61;100000
输出描述:
一行一个整数表示答案。
示例1
输入
3
1 2
1 3
输出
1
题目要求长度为偶数的路径数&#xff0c;那么先用链式前向星建图&#xff0c;然后从深度角度出发, 以 1 为根 dfs 求出全部深度
那么我们画个图观察一下&#xff0c;发现偶数层到偶数层 距离为偶数
奇数到奇数层 距离距离也为偶数
那么我们求出奇数层节点为a, 偶数层节点个数为b
答案为排列组合&#xff0c;C(a,2)&#43;C(b,2)C(a,2)&#43;C(b,2)C(a,2)&#43;C(b,2)
换成代码就是(a−1)∗a/2&#43;(b−1)∗b/2(a - 1) * a / 2 &#43; (b - 1) *b / 2(a−1)∗a/2&#43;(b−1)∗b/2
时间复杂度
O(n)O(n)O(n)
#include
#define ls (p<<1)
#define rs (p<<1|1)
#define mid (l&#43;r)/2
#define over(i,s,t) for(register long long i&#61;s;i<&#61;t;&#43;&#43;i)
#define lver(i,t,s) for(register long long i&#61;t;i>&#61;s;--i)
using namespace std;
typedef long long ll;
const ll N&#61;100007;
const ll INF&#61;1e10&#43;9;
const double EPS&#61;1e-10;
ll dep[N];
ll n,head[N],tot;
struct node
{ll v,nex;
}G[N<<1];
void add(ll u,ll v)
{G[&#43;&#43;tot].v&#61;v;G[tot].nex&#61;head[u];head[u]&#61;tot;
}void dfs(ll u,ll fa)
{dep[u]&#61;dep[fa]&#43;1;for(ll i&#61;head[u];i;i&#61;G[i].nex){if(G[i].v&#61;&#61;fa)continue;dfs(G[i].v,u);}
}
int main()
{scanf("%lld",&n);over(i,1,n-1){ll x,y;scanf("%lld%lld",&x,&y);add(x,y);add(y,x);}dfs(1,0);ll a&#61;0,b&#61;0;over(i,1,n)if(dep[i]&1)a&#43;&#43;;else b&#43;&#43;;printf("%lld\n",ll(a*(a-1)/2)&#43;ll(b*(b-1)/2));return 0;
}
还有一种树形DP我明天再写&#xff0c;先睡了
附上官方题解&#xff1a;
【每日一题】4月15日题目精讲