UVa 1267 - Network

传送门

UVa 1267 - Network

题意

一个服务器最多覆盖范围k,求放置最少的服务器覆盖所有叶子。

思路

按距离存入叶子,从距离最大的叶子开始向上数k个祖先放置服务器。把主服务器当成根。

代码

#include <cstdio>
#include <cstring>
#include <vector>
#define LL long long
#define lowbit(x) ((x) & (-x))
const int MAXN = 1000 + 5;
const int INF = 0x3f3f3f3f;
using namespace std;
 
vector<int> mp[MAXN], nodes[MAXN];
int pa[MAXN], covered[MAXN], k, n;
 
void Build(int cur, int f, int d)
{
    pa[cur] = f;
    int no = mp[cur].size();
    if (no == 1 && d > k)
        nodes[d].push_back(cur);
    for (int i = 0; i < no; i++)
    {
        int v = mp[cur][i];
        if (v != f) Build(v, cur, d + 1);
    }
}
 
void DFS(int cur, int f, int d)
{
    covered[cur] = 1;
    for (int i = 0; i < mp[cur].size(); i++)
    {
        int v = mp[cur][i];
        if (v != f && d < k)
            DFS(v, cur, d + 1);
    }
}
 
int Solve()
{
    memset(covered, 0, sizeof covered);
    int ans = 0;
    for (int d = n; d > k; d--)
    {
        for (int i = 0; i < nodes[d].size(); i++)
        {
            int t = nodes[d][i];
            if (covered[t]) continue;
            int v = t;
            for (int j = 0; j < k; j++)
                v = pa[v];
            DFS(v, -1, 0);
            ans++;
        }
    }
    return ans;
}
 
int main()
{
    //freopen("input.txt", "r", stdin);
    int T, i, j, s;
    scanf("%d", &T);
    while (T--)
    {
        scanf("%d%d%d", &n, &s, &k);
        for (int i = 1; i <= n; i++)
        {
            mp[i].clear();
            nodes[i].clear();
        }
        for (i = 0; i < n - 1; i++)
        {
            int a, b;
            scanf("%d%d", &a, &b);
            mp[a].push_back(b);
            mp[b].push_back(a);
        }
        Build(s, -1, 0);
        printf("%d\n", Solve());
    }
    return 0;
}

Powered by Jekyll and Theme by solid