zoukankan      html  css  js  c++  java
  • LA3902网络

    题意:
         给你一棵树,所有叶子节点都是客户端,其他的都是服务器,然后问你最少在多少个服务器上安装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 " ,Ans);
        }
        return 0;
    }    
            
               
                
            







  • 相关阅读:
    FormsAuthenticationTicket基于forms的验证
    JavaScript:Select标签
    Cookie编程入门篇
    SQL合并多表查询记录的存储过程
    JavaScript动态的为元素添加事件
    根据数据库表名查询该表字段名、字段类型、以及注释
    HttpHandler HttpModule入门篇
    XSLT的处理模型(1)
    jQuery.validate 中文API
    关于程序集生成失败 引用的程序集没有强名称的解决办法
  • 原文地址:https://www.cnblogs.com/csnd/p/12062641.html
Copyright © 2011-2022 走看看