小K的疑惑
题目链接:https://ac.nowcoder.com/acm/problem/20823
涉及知识点:
- 思维/搜索/简单图论
solution:
- 题目要求??????(??,??) = ??????(??,??) = ??????(??,??) ,首先要满足每两个节点的距离都是偶数,即??????(??,??) = ??????(??,??) = ??????(??,??) = 0
- 由于树上任意两点的距离是唯一的,所以如果i到j的距离是奇数,j到k的距离是奇数,那么i到k的距离一定是偶数
- 所以题目简化成找树上任意两点的距离是偶数的方案数
- 树上dp也是可行解,我们考虑简单的做法:
- 考虑以1号节点(任意节点都可以),到其余所有节点的距离,长度为偶数的记为k1 , 长度为奇数的记为k2(1号节点到1号节点的长度 = 0 ,也要算到答案中去)
- 那么答案其实就是k1×k1×k1 + k2×k2×k2
- 距离1号节点长度为奇数的也要算到里面,因为两条长度为奇数边相连就构成了偶数
- 这里的三次方意思就是(i, j ,k)位置上可以放置任意一个元素(组合数)
std:
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 100005;
int n;
struct node{
int x,z;
};
vector<node> v[maxn];
ll cnt1 = 0,cnt2 = 0;
void dfs(int x,int fa,int z)
{
if(z%2)cnt1++;
else cnt2++;
for(int i=0;i<v[x].size();i++){
if(v[x][i].x == fa)
continue ;
dfs(v[x][i].x , x , (z+v[x][i].z)%2);
}
}
int main()
{
cin>>n;
for(int i=1;i<n;i++){
int x,y,z;
cin>>x>>y>>z;
v[x].push_back(node{y , z});
v[y].push_back(node{x , z});
}
dfs(1, 0 , 0);
cout<<cnt1*cnt1*cnt1 + cnt2*cnt2*cnt2<<endl;
return 0;
}
原文地址:https://www.cnblogs.com/QFNU-ACM/p/12536460.html
时间: 2024-10-07 07:58:40