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

BZOJ 3522 POI 2014 Hotel 树形DP

时间:2015-04-08 10:56:19      阅读:161      评论:0      收藏:0      [点我收藏+]

标签:bzoj   poi   树形dp   

题目大意

给出一棵树,问选择三个点,使得这三个点相互的距离相等的方案有多少种。

思路

这三个点肯定不能再一条链上, 那么就肯定能够确定一个中心点,使得三个点到这个中心点的距离都相等。
之后我们就可以枚举这个中心点,对于每个深度统计一下就可以了。虽然看起来像是O(n3)的,但是跑的飞起啊。

CODE

#define _CRT_SECURE_NO_WARNINGS

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAX 5010
using namespace std;

int points;
int head[MAX], total;
int _next[MAX << 1], aim[MAX << 1];

inline void Add(int x, int y)
{
    _next[++total] = head[x];
    aim[total] = y;
    head[x] = total;
}

int deep[MAX];
int now;

void DFS(int x, int last, int d)
{
    ++deep[d];
    for(int i = head[x]; i; i = _next[i]) {
        if(aim[i] == last)  continue;
        DFS(aim[i], x, d + 1);
    }
}

long long cnt[MAX], ans[MAX];

int main()
{
    cin >> points;
    for(int x, y, i = 1; i < points; ++i) {
        scanf("%d%d", &x, &y);
        Add(x, y), Add(y, x);
    }
    long long output = 0;
    for(int x = 1; x <= points; ++x) {
        memset(cnt, 0, sizeof(cnt));
        memset(ans, 0, sizeof(ans));
        for(int i = head[x]; i; i = _next[i]) { 
            memset(deep, 0, sizeof(deep));
            DFS(aim[i], x, 1);
            for(int d = 1; d <= points; ++d) {
                output += ans[d] * deep[d];
                ans[d] += cnt[d] * deep[d];
                cnt[d] += deep[d];
            }
        }
    }
    cout << output << endl;
    return 0;
}

BZOJ 3522 POI 2014 Hotel 树形DP

标签:bzoj   poi   树形dp   

原文地址:http://blog.csdn.net/jiangyuze831/article/details/44937641

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