您的位置:首页 > 其它

ACM: uva 3902

2016-05-19 23:27 316 查看

Network

Consider a tree network with n nodes where
the internal nodes correspond to servers and the terminal nodes
correspond to clients. The nodes are numbered from 1 to
n . Among the servers, there is an original
server S which provides VOD (Video On Demand)
service. To ensure the quality of service for the clients, the
distance from each client to the VOD server S
should not exceed a certain value k . The
distance from a node u to a node
v in the tree is defined to be the number of
edges on the path from u to
v . If there is a nonempty subset
C of clients such that the distance from each
u in C to
S is greater than k , then
replicas of the VOD system have to be placed in some servers so
that the distance from each client to the nearest VOD server (the
original VOD system or its replica) is k or
less.

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

For example, consider the following tree network.



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 original
VOD server is located at node 12.

For k = 2 , the quality of service is not
guaranteed 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 or
more replicas. When one replica is placed at node 4, the distance
from each client to the nearest server of {12, 4} is less than or
equal to 2. The minimum number of the needed replicas is one for
this example.

Input 

Your program is to read the input from standard input. The input
consists of T test cases. The number of test
cases (T ) is given in the first line of the
input. The first line of each test case contains an integer
n (3

n

1,
000) which is the number of nodes of the tree network. The
next line contains two integers s
(1

s

n) and k
(k

1) where s is the VOD server and
k is the distance value for ensuring the
quality of service. In the following n - 1
lines, each line contains a pair of nodes which represent an edge
of the tree network.

Output 

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

Sample
Input 

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

Sample
Output 

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;

        }

  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: