码迷,mamicode.com
首页 > 其他好文 > 详细

3.21 每日一题题解

时间:2020-03-21 09:17:20      阅读:54      评论:0      收藏:0      [点我收藏+]

标签:==   std   dfs   else   main   思维   合数   节点   problem   

小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;
}

3.21 每日一题题解

标签:==   std   dfs   else   main   思维   合数   节点   problem   

原文地址:https://www.cnblogs.com/QFNU-ACM/p/12536460.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!