zoukankan      html  css  js  c++  java
  • LA3902 Network (树上dfs)

    题目链接:点击打开链接

    题意:n台机器连成一个树状网络,其中叶节点是客户端,其他节点是服务器,目前有一台服务器s正在提供服务。让你在其他服务器上也安排同样的服务,使得每台客户端到最近服务器的距离不超过k,而且要使服务器尽量少,问最少要设置多少台服务器。

    思路:我们先把s看做根节点,做一遍dfs,把离s距离小于等于k的叶子节点标为访问过,表示这个叶子节点已经得到服务了,然后再把没有访问过的叶子节点按深度从大到小排序,每次找到深度最大的点,在它的k倍祖先上放服务器,然后dfs一遍,把离它距离不超过k的叶子节点都标为访问过。


    #include<iostream>
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<math.h>
    #include<vector>
    #include<map>
    #include<set>
    #include<queue>
    #include<stack>
    #include<string>
    #include<bitset>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    typedef long double ldb;
    #define inf 99999999
    #define pi acos(-1.0)
    #define maxn 1005
    #define MOD 1000000009
    vector<int>vec[maxn];
    vector<int>deep[maxn];
    vector<int>::iterator it;
    int vis[maxn],fa[maxn];
    int k;
    
    void dfs(int u,int pre,int dep)
    {
        int i,j,flag=0;
        fa[u]=pre;
        if(dep+1<=k+1)vis[u]=1;
        for(i=0;i<vec[u].size();i++){
            int v=vec[u][i];
            if(v!=pre){
                flag=1;
                dfs(v,u,dep+1);
            }
        }
        if(!flag)deep[dep+1].push_back(u);
    
    }
    
    void dfs2(int u,int pre,int num)
    {
        int i,j;
        vis[u]=1;
        if(num==k)return;
        for(i=0;i<vec[u].size();i++){
            int v=vec[u][i];
            if(v!=pre){
                dfs2(v,u,num+1);
            }
        }
    }
    
    
    int main()
    {
        int n,m,i,j,T,s,c,d,h;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d",&n);
            scanf("%d%d",&s,&k);
            for(i=1;i<=1003;i++){
                vec[i].clear();
                deep[i].clear();
            }
            memset(fa,0,sizeof(fa));
            memset(vis,0,sizeof(vis));
    
    
            for(i=1;i<=n-1;i++){
                scanf("%d%d",&c,&d);
                vec[c].push_back(d);
                vec[d].push_back(c);
            }
    
            dfs(s,0,0);
            int cnt=0;
            for(h=n;h>k+1;h--){
                for(i=0;i<deep[h].size();i++){
                    if(vis[deep[h][i] ])continue;
                    int jiedian=deep[h][i];
                    for(j=1;j<=k;j++){
                        jiedian=fa[jiedian];
                    }
                    cnt++;
                    dfs2(jiedian,-1,0);
                }
            }
            printf("%d
    ",cnt);
        }
        return 0;
    }
    
    /*
    100
    10
    1 1
    1 2
    1 3
    1 4
    2 5
    2 6
    3 7
    3 8
    5 9
    5 10
    */
    


  • 相关阅读:
    Tiny64140之初始化时钟
    Tiny6410之控制icache驱动
    Tiny6410之按键裸机驱动
    Linux -- man 、info、 whatis、 -h
    Linux -- which whereis
    Linux -- sudoers (简单:转)
    Linux -- sudo
    Linux -- sudoers文件
    Linux -- cp
    Linux -- mv
  • 原文地址:https://www.cnblogs.com/herumw/p/9464500.html
Copyright © 2011-2022 走看看