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

sgu280:Trade centers(贪心构造)

时间:2015-06-26 15:04:49      阅读:94      评论:0      收藏:0      [点我收藏+]

标签:

题目大意:
      给定一棵n个结点的树,从中选出一个最小点集S,使得树中每一个点到点集的最小距离k

分析:
      根据贪心原则,每两个S中的点,尽量使得两个点之间的距离=2k+1,因为如果两个点距离2k+1,中间所有的点都是可以覆盖得到的。
      fi表示i到子树中某一个S中的点的距离。
      如果i为叶子结点,fi=k+1,表示它只能由kth ancestor覆盖(看不懂请往下)
      如果i有一个孩子j,那么fi=fj+1
      如果i有两个以上的孩子,那么从孩子中选一个最大的fmax,和最小的fmin。如果fmin+fmax2k+1,表示这棵子树中所有的点都可以被覆盖,fi=fmin+1,没必要再选根结点;如果fmin+fmax>2k+1,表示这棵子树中所有的点没有都被覆盖,那么这时fi=fmax+1。如果fi=2k+1,那么将这个点加入S中,fi置为0
      对于根节点,如果f1>k那么也要将其加入S中。

AC code:

#include <cstdio>
#include <vector>
#include <algorithm>
#define pb push_back
using namespace std;

const int MAXN = 30009;
const int INF = 0x3f3f3f3f;

int n, k;
int rank[MAXN];
bool is[MAXN];
vector<int> ans;

struct Ugraph
{
    int size;
    int head[MAXN];
    int to[MAXN<<1];
    int ne[MAXN<<1];
    Ugraph() {size = 1;}
    void add_edge(int u, int v)
    {
        to[size] = v, ne[size] = head[u], head[u] = size++;
        to[size] = u, ne[size] = head[v], head[v] = size++;
    }
}G;

void dfs(int x, int fa)
{
    int y, minr = INF, maxr = -INF, c = 0;
    for(int i = G.head[x]; i; i = G.ne[i])
    {
        y = G.to[i];
        if(y != fa)
        {
            dfs(y, x);
            minr = min(minr, rank[y]);
            maxr = max(maxr, rank[y]);
            c++;
        }
    }
    if(!c) rank[x] = k+1;
    else if(c == 1) rank[x] = minr+1;
    else 
    {
        if(minr+maxr+2 <= 2*k+1) rank[x] = minr+1;
        else rank[x] = maxr+1;
    }
    if(rank[x] == 2*k+1) is[x] = true, rank[x] = 0;
}

int main()
{
    #ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    #endif

    scanf("%d%d", &n, &k);
    for(int i = 1; i < n; ++i)
    {
        int u, v;
        scanf("%d%d", &u, &v);
        G.add_edge(u, v);
    }
    dfs(1, 0);
    for(int i = 1; i <= n; ++i)
        if(is[i] || (i == 1 && rank[i] > k))
            ans.pb(i);
    printf("%d\n", ans.size());
    for(int i = 0, sz = ans.size(); i < sz; ++i)
        printf("%d\n", ans[i]);

    #ifndef ONLINE_JUDGE
    fclose(stdin);
    fclose(stdout);
    #endif
    return 0;
}

sgu280:Trade centers(贪心构造)

标签:

原文地址:http://blog.csdn.net/qq_20118433/article/details/46649099

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