前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >POJ PKU 3659 Cell Phone Network 解题报告

POJ PKU 3659 Cell Phone Network 解题报告

作者头像
owent
发布2018-08-01 17:21:28
2420
发布2018-08-01 17:21:28
举报
文章被收录于专栏:owentowent

题目链接:http://acm.pku.edu.cn/JudgeOnline/problem?id=3659

这题不算难题了,基本算是中等题

题目大意是给出一颗树,在一些点建一个信号塔,信号塔覆盖范围是其所在点和邻近点,问最少几个信号塔可以覆盖全区域

思路是树状DP(后序遍历),有三个状态,分别记录父节点建塔,本节点建塔和子节点建塔的最少建塔数量

需要注意的就是子节点建塔的判断,子节点建塔只要一个以上的子节点建塔即可

代码如下:

代码语言:javascript
复制
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <cmath>
using namespace std;

struct node
{
    vector<int> linkto;
    int build[3];//0 为自己建塔, 1 为父节点建塔, 2为子节点建塔
};

node pasture[10005];

int calcPos(int pos, int f);
int main()
{
    int i, j, n, a, b, res;

    scanf("%d", &n);
    for(i = 0; i < n - 1; i ++)
    {
        scanf("%d %d", &a, &b);
        pasture[a - 1].linkto.push_back(b - 1);
        pasture[b - 1].linkto.push_back(a - 1);
    }

    calcPos(0, 0);
    res = min(pasture[0].build[0], pasture[0].build[2]);

    printf("%d\n", res);
    return 0;
}

int calcPos(int pos, int f)
{
    int i, tmp;
    bool flag = false;
    pasture[pos].build[0] = 1;
    pasture[pos].build[1] = 0;
    pasture[pos].build[2] = 0;

    for(i = 0; i < pasture[pos].linkto.size(); i ++)
    {
        if(pasture[pos].linkto[i] != f)
        {
            calcPos(pasture[pos].linkto[i], pos);
            pasture[pos].build[0] += min(min(pasture[ pasture[pos].linkto[i] ].build[0], pasture[ pasture[pos].linkto[i] ].build[1])
                , pasture[ pasture[pos].linkto[i] ].build[2]);
            pasture[pos].build[1] += min(pasture[ pasture[pos].linkto[i] ].build[0], pasture[ pasture[pos].linkto[i] ].build[2]);
            pasture[pos].build[2] += min(pasture[ pasture[pos].linkto[i] ].build[0], pasture[ pasture[pos].linkto[i] ].build[2]);
            flag = flag || (pasture[ pasture[pos].linkto[i] ].build[0] <= pasture[ pasture[pos].linkto[i] ].build[2]);
        }
    }

    if(pasture[pos].build[2] == 0)
    {
        pasture[pos].build[2] = 100000;
        return 0;
    }
    if(flag == false)
    {
        tmp = 100000;
        for(i = 0; i < pasture[pos].linkto.size(); i ++)
        {
            if(pasture[pos].linkto[i] != f
                && pasture[pasture[pos].linkto[i]].build[0] - pasture[pasture[pos].linkto[i]].build[2] < tmp)
            tmp = pasture[pasture[pos].linkto[i]].build[0] - pasture[pasture[pos].linkto[i]].build[2];
        }
        pasture[pos].build[2] += tmp;
    }
    return 0;
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2010-06-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档