0
点赞
收藏
分享

微信扫一扫

LA3902网络

笙烛 2022-07-27 阅读 59

题意:
     给你一棵树,所有叶子节点都是客户端,其他的都是服务器,然后问你最少在多少个服务器上安装VOD能使所有的客户端都能流畅的看视频,流畅看视频的条件是每个客户端距离他最近的安装VOD的服务器的距离不能超过k,而且题目已经给你在一个服务器上安装好了VOD。


思路:
     自己没想出来,说下白书上的思路,第一个就是说当遇到无根树的时候,一般情况下把无根树变成有根数会有利于问题的解决,然后这个题目就是把给定的VOD服务器变成了树根,然后我们可以根据贪心策略,先处理深度最深的,安装VOD是在当前深度最深的上面第k个父亲那安装VOD这样是为了尽可能多的去让别的客户端能用上这个VOD,然后就是模拟这个过程了,这个思路是白书上说的,我想了一阵子,只是感觉有道理,但并不能肯定他的正确性,说白了就是还没弄清楚这样为什么是对的,以后会重新编辑这篇博客。
     

#include<stdio.h>

#include<string.h>



#define N 1000+5

#define N_node 1000 + 5

#define N_edge 2000 + 10



typedef struct

{

int to ,next;

}STAR;



STAR E[N_edge];

int list[N_node] ,tot;



int mark[N] ,mk[N] ,deep[N];

int dis[N][N] ,mer[N];



void add(int a ,int b)

{

E[++tot].to = b;

E[tot].next = list[a];

list[a] = tot;

}



//deep mark



void DFS1(int s ,int fa)

{

int mk = 0;

for(int k = list[s] ;k ;k = E[k].next)

{

int to = E[k].to;

if(to == fa) continue;

mk = 1;

mer[to] = s;

deep[to] = deep[s] + 1;

DFS1(to ,s);

}

mark[s] = !mk;

}



//dis

void DFS2(int sss ,int now ,int s ,int fa)

{

for(int k = list[s] ;k ;k = E[k].next)

{

int to = E[k].to;

if(to == fa) continue;

dis[sss][to] = now;

DFS2(sss ,now + 1 ,to ,s);

}

}



int main ()

{

int n ,s ,k ,i ,j ,t ,a ,b;

scanf("%d" ,&t);

while(t--)

{

scanf("%d %d %d" ,&n ,&s ,&k);

memset(list ,0 ,sizeof(list)) ,tot = 1;

for(i = 1 ;i < n ;i ++)

{

scanf("%d %d" ,&a ,&b);

add(a ,b) ,add(b ,a);

}

for(i = 1 ;i <= n ;i ++) mer[i] = i;

deep[s] = 0;

DFS1(s ,-1);

for(i = 1 ;i <= n ;i ++)

{

dis[i][i] = 0;

DFS2(i ,1 ,i ,-1);

}



memset(mk ,0 ,sizeof(mk));

for(i = 1 ;i <= n ;i ++)

if(mark[i] && dis[s][i] <= k)

mk[i] = 1;

int Ans = 0;

while(1)

{

int mkid = 0 ,maxdeep = 0;

for(i = 1 ;i <= n ;i ++)

{

if(!mark[i] || mk[i]) continue;

if(maxdeep < deep[i])

maxdeep = deep[i] ,mkid = i;

}

if(!mkid) break;

Ans ++;

int maxdis = 0 ,mknode = 0;

mknode = mkid;

for(i = 1 ;i <= k ;i ++)

mknode = mer[mknode];

for(i = 1 ;i <= n ;i ++)

{

if(!mark[i] || mk[i]) continue;

if(dis[mknode][i] <= k) mk[i] = 1;

}

}

printf("%d\n" ,Ans);

}

return 0;

}

举报

相关推荐

0 条评论