LA 3902

  之前对树的处理一般是从根节点开始递归处理。今天学习了一种新方法,根据层的深浅处理。即,1、首先得到每个节点的深度 2、然后从最底层开始处理。(貌似是宽搜的逆处理)

题意:给出一个棵树,从根节点向叶节点发信息。如果距离大于k就无法发送信息(节点之间的距离为1)。 为了能够给所有叶节点传送到信息,需要在树立增加一些服务器,这些服务器也能发送信息,如果一个叶节点离最近的服务器距离不超过k,那么也认为这个叶节点是接收到信息的。求最少需要增加多少个服务器可以让所有的叶节点都能收到信息。

思路:开始的时候就认为是一个树形dp,想了一会儿想出了办法,但是处理比较复杂。后来发现了一个方便,处理比较好一点。

可以发现深度不大于k的叶节点不需要管。 对于深度大于k的叶节点,我们优先处理较深节点。对于当前未处理的节点,我们优先处理最深的节点,将服务器放到最深节点的前k层祖先的位置不会让最优结果变坏。 我们放一个服务器后需要将距离服务器距离不大于k的叶节点全部染色(即处理)。

AC代码:

#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;

const int N = 1050;

int n, k, s;
vector<int>edge[N];
vector <int> g[N];
bool covered[N];
int f[N];

void init()
{
    scanf("%d", &n);
    scanf("%d%d", &s, &k);
    int u, v;
    for(int i=0; i<=n; i++)
    {
        edge[i].clear();
        g[i].clear();
    }
    for(int i=1; i<n; i++)
    {
        scanf("%d%d", &u, &v);
        edge[u].push_back(v);
        edge[v].push_back(u);
    }
}

void dfs(int u, int pre, int d)
{
    f[u] = pre;
    int sz = edge[u].size(), v;
    if(sz == 1 && d > k)
    {
        g[d].push_back(u);
    }
    for(int i=0; i<sz; i++)
    {
        v = edge[u][i];
        if(v == pre) continue;
        dfs(v, u, d+1);
    }
}

void dfs2(int u, int pre, int d)
{
    covered[u] = true;
    int v = 0;
    for(int i=0; i<edge[u].size(); i++)
    {
        v = edge[u][i];
        if(v == pre) continue;
        if(d < k)
        {
            dfs2(v, u, d+1);
        }
    }
}

void solve()
{
    dfs(s, -1, 0);
    memset(covered, 0, sizeof(covered));
    int ans = 0, u, v;
    for(int i=n-1; i>k; i--)
    {
        for(int j=0; j<g[i].size(); j++)
        {
            u = g[i][j];
            if(covered[u]) continue;
            v = u;
            for(int j=0; j<k; j++) v = f[v];
            dfs2(v, -1, 0);
            ans++;
        }
    }
    printf("%d\n", ans);
}

int main()
{
    int t;
    scanf("%d", &t);
    while(t--)
    {
        init();
        solve();
    }
    return 0;
}

时间: 2024-10-12 08:18:45

LA 3902的相关文章

LA 3902 网络

题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1903 题意: n 台计算机,n-1条边成树,有一个服务器,给定一个 k ,要求所有叶子结点,距离服务器的距离 <=k: 所以要在一些地方放服务器: 问最少要放多少个服务器? 图中要在 4 号结点放一个服务器,k = 2; 分析: 1.无根树要转有根树 从下往上

Uva 网络(Network,Seoul 2007,LA 3902)

1 #include<iostream> 2 #include<cstring> 3 #include<vector> 4 using namespace std; 5 6 const int maxn=1000+10; 7 int n,s,k; 8 vector<int> tree[maxn],nodes[maxn]; 9 int fa[maxn]; 10 bool covered[maxn]; 11 12 void dfs(int u,int f,int

LA 3902 Network

贪心的思想吧,对于每一个还没被覆盖到的叶子节点,最优的选择就是他的k级祖先(节点的父亲为1级祖先). 记录下各深度的叶子节点,这对于这些节点选择一个最优的祖先节点,然后从选出的这个祖先节点向外扩展,把该点能覆盖到的叶子节点全都标记.按深度从深到浅使每个叶子节点都被覆盖后,既是ans #include <map> #include <cmath> #include <cstdio> #include <vector> #include <string&g

hdu 5745 la vie en rose

这道题的官方题解是dp,但是可以暴力出来.改天再研究怎么dp. 暴力的时候,如果计算sum的时候,调用strlen函数会超时,可见这个函数并不是十分的好.以后能不用尽量不用. La Vie en rose Time Limit: 14000/7000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 861    Accepted Submission(s): 461 Problem

让MAC OS也能使用LL LA L等LS的别名

linux下默认ll是ls -l的别名.OS X下默认不支持.习惯了linux下使用ll,我们同样也可以将习惯搬到os x下的shell中. 再当前用户家目录下新建.bash_profile文件.根据你的习惯,添加下面格式内容即可. 1 2 3 alias ll='ls -l' alias la='ls -a' alias l='ls -la' 然后执行:source .bash_profile你还可以添加你喜欢的其他别名.

LA 3942 Remember the Word (Trie)

Remember the Word 题目:链接 题意:给出一个有S个不同单词组成的字典和一个长字符串.把这个字符串分解成若干个单词的连接(单词可以重复使用),有多少种方法? 思路:令d[i]表示从字符i开始的字符串(后缀s[i..L])的分解数,这d[i] = sum{d(i+len(x)) | 单词x是其前缀}.然后将所有单词建成一个Trie树,就可以将搜索单词的复杂度降低. 代码: #include<map> #include<set> #include<queue>

LA 2678 Subsequence

有一个正整数序列,求最短的子序列使得其和大于等于S,并输出最短的长度. 用数组b[i]存放序列的前i项和,所以b[i]是递增的. 遍历终点j,然后在区间[0, j)里二分查找满足b[j]-b[i]≥S的最大的i,时间复杂度为O(nlongn). 这里二分查找用到库函数lower_bound() 1 //#define LOCAL 2 #include <iostream> 3 #include <cstdio> 4 #include <cstring> 5 #inclu

LA 4127 - The Sky is the Limit (离散化 扫描线 几何模板)

题目链接 非原创 原创地址:http://blog.csdn.net/jingqi814/article/details/26117241 题意:输入n座山的信息(山的横坐标,高度,山底宽度),计算他们的轮廓线, 即露出来的表面边长,有些山是重叠的不计.空白地带不计,每座山都是等腰三角形. 分析:大白书P414页. 求小山的总长度,用一些虚线将其离散化,分成一段一段的,特征点:山脚,山顶,交点.这样就能保 证相邻两个扫描点之间再无交点.然后一最上面的点就是分割点,维护上一个点lastp即可. 1

LA 2031

Mr. White, a fat man, now is crazy about a game named ``Dance, Dance, Revolution". But his dance skill is so poor that he could not dance a dance, even if he dances arduously every time. Does ``DDR" just mean him a perfect method to squander his