ACM: uva 3902

来源:互联网 发布:电脑网络连接显示未知 编辑:程序博客网 时间:2024/05/19 09:17

Network

Consider a tree network with n nodes wherethe internal nodes correspond to servers and the terminal nodescorrespond to clients. The nodes are numbered from 1 ton . Among the servers, there is an originalserver S which provides VOD (Video On Demand)service. To ensure the quality of service for the clients, thedistance from each client to the VOD server Sshould not exceed a certain value k . Thedistance from a node u to a nodev in the tree is defined to be the number ofedges on the path from u tov . If there is a nonempty subsetC of clients such that the distance from eachu in C toS is greater than k , thenreplicas of the VOD system have to be placed in some servers sothat the distance from each client to the nearest VOD server (theoriginal VOD system or its replica) is k orless.

Given a tree network, a server S which hasVOD system, and a positive integer k , find theminimum number of replicas necessary so that each client is withindistance k from the nearest server which hasthe original VOD system or its replica.

For example, consider the following tree network.

\epsfbox{p3902.eps}

In the above tree, the set of clients is {1, 6, 7, 8, 9, 10, 11,13}, the set of servers is {2, 3, 4, 5, 12, 14}, and the originalVOD server is located at node 12.

For k = 2 , the quality of service is notguaranteed with one VOD server at node 12 because the clients in{6, 7, 8, 9, 10} are away from VOD server at distance> k . Therefore, we need one ormore replicas. When one replica is placed at node 4, the distancefrom each client to the nearest server of {12, 4} is less than orequal to 2. The minimum number of the needed replicas is one forthis example.

Input 

Your program is to read the input from standard input. The inputconsists of T test cases. The number of testcases (T ) is given in the first line of theinput. The first line of each test case contains an integern (3$ \le$n$ \le$1,000) which is the number of nodes of the tree network. Thenext line contains two integers s(1$ \le$s$ \le$n) and k(k$ \ge$1) where s is the VOD server andk is the distance value for ensuring thequality of service. In the following n - 1lines, each line contains a pair of nodes which represent an edgeof the tree network.

Output 

Your program is to write to standard output. Print exactly oneline for each test case. The line should contain an integer that isthe minimum number of the needed replicas.

SampleInput 

2 14 
12 2
1 2
2 3
3 4
4 5
5 6
7 5
8 5
4 9
10 3
2 12
12 14
13 14
14 11
14
3 4
1 2
2 3
3 4
4 5
5 6
7 5
8 5
4 9
10 3
2 12
12 14
13 14
14 11

SampleOutput 

1 
0

题意: 在图结构上放置服务器, 每个服务能覆盖的范围不超过K, 现在要你选择最少的节点放置服务器,
      使得整个图被覆盖.图上有n个节点, n-1条边.

解题思路:
     1. 因为原来图上已经有1个点被放置了服务器, 以它为根, 将图转化为树结构, 这样考虑深度
        覆盖不超过K, 先重深度最大的叶子节点开始覆盖, 当然这里选择于叶子节点深度差为K的
        节点放置服务器最优.

代码:
#include <cstdio>
#include <iostream>
#include <cstring>
#include <vector>
using namespace std;
#define MAX 1005

int n, s, K;
vector g[MAX], deep[MAX];
int fa[MAX];
int covered[MAX];

void dfs(int u, int f, int cur)
{
    fa[u] = f;
    int num = g[u].size();
    if(num == 1 && cur > K)
        deep[cur].push_back(u);
    for(int i = 0; i < num; ++i)
    {
        int v = g[u][i];
        if(v != f) dfs(v, u, cur+1);
    }
}

void cover(int u, int f, int cur)
{
    covered[u] = 1;
    int num = g[u].size();
    for(int i = 0; i < num; ++i)
    {
        int v = g[u][i];
        if(v != f && cur < K) cover(v, u, cur+1);
    }
}

int solve()
{
    int result = 0;
    memset(covered, 0, sizeof(covered));
    for(int i = n-1; i > K; --i)
    {
        for(int j = 0; j < deep[i].size(); ++j)
        {
            int u = deep[i][j];
            if(covered[u]) continue;
           
            int v = u;
            for(int k = 0; k < K; ++k) v = fa[v];
            cover(v, -1, 0);
            result++;
        }
    }
    return result;
}

int main()
{
//    freopen("input.txt", "r", stdin);
    int caseNum;
    scanf("%d", &caseNum);
    while(caseNum--)
    {
        scanf("%d %d %d", &n, &s, &K);
        for(int i = 0; i < n; ++i)
        {
            g[i].clear();
            deep[i].clear();
            fa[i] = 0;
        }
       
        int u, v;
        for(int i = 0; i < n-1; ++i)
        {
            scanf("%d %d", &u, &v);
            g[u].push_back(v);
            g[v].push_back(u);
        }
       
        dfs(s, -1, 0);
        printf("%d\n", solve());
    }
    return 0;
}
0 0