寒假集訓 Day 7 H題 UVALive - 3902 Network 網絡

UVALive - 3902 Network 網絡


題目大意:

n臺機器連成一個樹狀網絡,其中葉節點是客戶端,其他節點是服務器。現在有一臺服務器在節點s,服務器能傳播的信號的距離爲k,因爲有的用戶距離服務器的距離大於k,所以必須添加服務器。問最少要添加幾個服務器,才能使每個客戶端都收到信號。


解題思路:

  • 用 STL 的 vector 建圖,一個 G[maxN] 存儲圖的信息 ;同時用 P[dis] 存儲深度大於 k ( 存儲的葉子節點的深度即爲 dis )的葉子節點;此外還要記錄下每個節點的雙親(即以 s 爲根將此圖轉化爲有根樹)。

  • 對P[dis] 從dis最大處遍歷到最小處 ,用 coverd 標記已經被服務器覆蓋的節點, 當遇到沒有被覆蓋的葉子節點時, ans++ 。

  • 上個過程,遇到沒有被覆蓋的葉子節點時,服務器要設立在此葉子節點的前 k 代祖先處。


AC代碼:

#include <iostream>
#include <cstdio>
#include <cstring>
#include<vector>
#define rep(i,l,p) for(int i=l;i<=p;i++)
#define rush() int T; scanf("%d",&T); while(T--)
using namespace std;
const int maxN = 1005;
const int maxM = 1000005;

int n,s,k,pars[maxN];
vector<int> G[maxN],P[maxN];
int coverd[maxN];
void dfs(int u,int par,int dis){
    pars[u] = par;
    for(int i = 0; i<G[u].size();i++){
        int v = G[u][i];
        if ( v == par ) continue;
        if ( dis +1 > k && G[v].size() == 1){
            P[dis+1].push_back(v);
        } 
        dfs(v,u,dis+1);
    }
}
void dfs2(int u,int par,int dep){
    if ( dep > k ) return;
    coverd[u] = 1;
    //int ecnt = G[u].size();
    for(int i = 0; i <G[u].size(); i++){    
        int v = G[u][i];
    //  if ( coverd[v] ) continue;//下次到來可能可以走到更深

        if(v != par)dfs2(v,u,dep+1);
    }
}
int solve(){
    int ans = 0;
    for(int i = n-1;i>k;i--){
        if (P[i].size()){
            for(int j = 0;j<P[i].size();j++){
                int anc = P[i][j];
                if ( coverd[anc] ) continue;
                rep(i,1,k){
                    anc = pars[anc];
                }
                ans++;
                dfs2(anc,-1,0);
            }
        }
    }
    printf("%d\n", ans);
}
void input(){
    memset(coverd,0,sizeof(coverd));
    memset(pars,0,sizeof(pars));

    scanf("%d%d%d",&n,&s,&k);
    for(int i = 0;i<=n;i++){
        if ( G[i].size() ) G[i].clear();
        if ( P[i].size() ) P[i].clear();  //開始忘了初始化
    }
    //cout << n << s << k << endl;
    int u,v;
    rep(i,1,n-1){
        scanf("%d%d",&u,&v);
        G[u].push_back(v);
        G[v].push_back(u);
    }
    dfs(s,-1,0);

}
int main(int argc, char const *argv[])
{
    //freopen("in.txt","r",stdin);
    rush(){

        input();
        solve();
    }
    return 0;
}
發佈了37 篇原創文章 · 獲贊 5 · 訪問量 3667
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章