思维+dfs+奇偶数安排问题

链接:https://www.nowcoder.com/acm/contest/106/A
来源:牛客网


It’s universally acknowledged that there’re innumerable trees in the campus of HUST.  


One day, zjh is wandering in the campus,and he finds a tree with n monkeys on it, and he labels the monkeys from 1 to n. A triple of monkeys (a,b,c) is called happy if and only if the absolute value of the difference of the distance from c to a the distance from c to b holds the same parity(奇偶性) as n. Now zjh wants to know how many triples of monkeys are happy.
输入描述:
There are multiple test cases. 
The first line of input contains an integer T, indicating the number of test cases. 
For each test case:
The first line contains an integer n
In the next n-1 lines, each line contains two integers ui and vi, denoting an edge between monkey ui and monkey v­i.
输出描述:
For each test case, output an integer S, denoting the number of triple of monkeys that are happy.
示例1
输入


1
3
1 2
2 3
输出


12
说明


The 12 triples are:
(1,2,1)
(1,2,2)
(1,2,3)
(2,1,1)
(2,1,2)
(2,1,3)
(2,3,1)
(2,3,2)
(2,3,3)
(3,2,1)
(3,2,2)

(3,2,3)

题意:大概是有一堆猴子,从中找出三个位置(可重复)然后使得a,b,c这三个位置abs(abs(a-b)-abs(a-c))的距离的奇偶性与n的奇偶性一致。

思路:

这道题的难度就在于怎么安排奇数偶数,需要自行找出规律

①:如果n是奇数的话,只能是    偶+奇+偶     或者    奇+偶+奇   或者      奇,偶,偶      或者   ,偶奇奇    

所以就是    ans=oushu*jishu*oushu*2;

                  ans+=jishu*oushu*jishu*2;

②:如果n是偶数的话,只能是   偶偶奇,偶偶偶,奇奇奇,   奇奇偶  

  所以就是    ans+=(jishu*jishu+oushu*oushu)*n

    因为  偶偶奇+偶偶偶=(偶偶)所有

所以我们就只需要找出根节点1到其他点的距离就好了,利用dfs求深度。

代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn=100005;
vector<int>lala[maxn];
int dis[maxn];
long long ans;
void dfs(int u,int fa,int dep)
{
    dis[u]=dep;
    for(int i=0;i<lala[u].size();i++)
    {
        int v=lala[u][i];
        if(v==fa)
            continue;
        dfs(v,u,dep+1);
    }
    return;
}
int main()
{
    int t;
    long long oushu,jishu;
    int u,v;
    scanf("%d",&t);
    int n;
    while(t--)
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            lala[i].clear();
        }
        for(int i=1;i<n;i++)
        {
            scanf("%d%d",&u,&v);
            lala[u].push_back(v);
            lala[v].push_back(u);
        }
        dfs(1,1,1);
        oushu=0;
        jishu=0;
        for(int i=1;i<=n;i++)
        {
            if(dis[i]%2==1)
            jishu++;
            else
                oushu++;
        }
        ans=0;
        if(n%2==1)
        {
            ans=oushu*jishu*oushu*2;
            ans+=jishu*oushu*jishu*2;
            printf("%lld\n",ans);
        }
        else//如果是偶数的话
        {
            ans+=(oushu*oushu+jishu*jishu)*n;
            printf("%lld\n",ans);
        }
    }
    return 0;
}







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值