题目链接:https://ac.nowcoder.com/acm/problem/14248
题意:给你一颗树,相邻结点间的距离为1,问你节点间距离为偶数的点对有多少对。
思路:这一题我们可以先以任意一个节点作为根节点,跑一遍
B
F
S
/
D
F
S
BFS/DFS
BFS/DFS,那我们就可以处理出所有点到根节点的距离。
那我们可以想到:
- 所有到根节点距离为奇数的点对之间的距离为偶数;
- 所有到更节电距离为偶数的点对直接的距离为偶数。
我们用遍
c
n
t
1
cnt1
cnt1和
c
n
t
2
cnt2
cnt2表示到根节点距离为奇数和偶数的节点个数,那么最后答案就是
c
n
t
1
∗
(
c
n
t
−
1
)
/
2
+
c
n
t
2
∗
(
c
n
t
2
−
1
)
/
2
cnt1*(cnt-1)/2+cnt2*(cnt2-1)/2
cnt1∗(cnt−1)/2+cnt2∗(cnt2−1)/2.
PS. 记得开
l
o
n
g
l
o
n
g
long long
longlong
AC代码:
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <cmath>
#include <ctime>
#include <vector>
#include <cstdio>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define LL long long
#define pii pair<int,int>
#define sd(x) scanf("%d",&x)
#define slld(x) scanf("%lld",&x)
#define pd(x) printf("%d\n",x)
#define plld(x) printf("%lld\n",x)
#define rep(i,a,b) for(int i = (a) ; i <= (b) ; i++)
#define per(i,a,b) for(int i = (a) ; i >= (b) ; i--)
#define mem(a) memset(a,0,sizeof(a))
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1
#define fast_io ios::sync_with_stdio(false)
const int INF = 1e9;
const LL mod = 1e9 + 7;
const int maxn = 1e5 + 7;
int head[maxn << 1];
struct Edge {
int to,next;
}edge[maxn << 1];
int tot;
void init() {
memset(head,-1,sizeof(head));
tot = 0;
}
void addedge(int u,int v) {
edge[tot].to = v;
edge[tot].next = head[u];
head[u] = tot++;
}
int dep[maxn];
void dfs(int u,int fa) {
for(int i = head[u] ; i != -1 ; i = edge[i].next) {
int v = edge[i].to;
if(v == fa) continue;
dep[v] = dep[u] + 1;
dfs(v,u);
}
}
int main() {
int n;
sd(n);
init();
rep(i,1,n-1) {
int u,v;
sd(u),sd(v);
addedge(u,v);
addedge(v,u);
}
dep[1] = 0;
dfs(1,0);
int cnt1 = 0 , cnt2 = 0;
rep(i,1,n) {
if(dep[i] & 1) cnt1++;
else cnt2++;
}
LL ans = 1LL * cnt1 * (1LL * cnt1 - 1LL) / 2LL + 1LL * cnt2 * (1LL * cnt2 - 1LL) / 2LL;
plld(ans);
return 0;
}