UVA - 1267 Network
2082 ワード
题意:n台の机械は1つの木の状のネットワークにつながって、その中の叶のノードはクライアントで、その他のノードはサーバーで、今1台のサーバーはサービスを提供して、あなたの任务はいくつかのその他のサーバーでインストールしてそれにサービスを提供させて、1台のクライアントから最近のサーバーまでの距离はKを超えないで、インストールの最低のサーバーはいくらです
考え方:無根樹を有根樹に変えることは問題を解くのに役立ち、本題にはすでに天然の根ノードがあり、条件を満たすノードは直接存在しないと見なせばよい.一般に、リーフノードuについては、uのkレベルの祖先を選択してサーバをインストールし、サーバを1回置くたびにDFSを行い、Kを超えないすべてのノードタグを選択します.
この問題の最適な点は、nodesテーブルを使用して「深さでソート」する操作を避けることです.
考え方:無根樹を有根樹に変えることは問題を解くのに役立ち、本題にはすでに天然の根ノードがあり、条件を満たすノードは直接存在しないと見なせばよい.一般に、リーフノードuについては、uのkレベルの祖先を選択してサーバをインストールし、サーバを1回置くたびにDFSを行い、Kを超えないすべてのノードタグを選択します.
この問題の最適な点は、nodesテーブルを使用して「深さでソート」する操作を避けることです.
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
const int MAXN = 1010;
vector<int> gr[MAXN],nodes[MAXN];
int n,s,k,fa[MAXN];
bool covered[MAXN];
void dfs(int u,int f,int d){
fa[u] = f;
int nc = gr[u].size();
if (nc == 1 && d > k) //
nodes[d].push_back(u);
for (int i = 0; i < nc; i++){
int v = gr[u][i];
if (v != f)
dfs(v,u,d+1);
}
}
void dfs2(int u,int f,int d){
covered[u] = true;
int nc = gr[u].size();
for (int i = 0; i < nc; i++){
int v = gr[u][i];
if (v != f && d < k)
dfs2(v,u,d+1);
}
}
int solve(){
int ans = 0;
memset(covered,0,sizeof(covered));
for (int d = n-1; d > k; d--)
for (int i = 0; i < nodes[d].size(); i++){
int u = nodes[d][i];
if (covered[u])
continue;
int v = u;
for (int j = 0; j < k; j++)
v = fa[v];
dfs2(v,-1,0);
ans++;
}
return ans;
}
int main(){
int t;
scanf("%d",&t);
while (t--){
scanf("%d%d%d",&n,&s,&k);
for (int i = 1; i <= n; i++){
gr[i].clear();
nodes[i].clear();
}
for (int i = 0; i < n-1; i++){
int a,b;
scanf("%d%d",&a,&b);
gr[a].push_back(b);
gr[b].push_back(a);
}
dfs(s,-1,0);
printf("%d
",solve());
}
return 0;
}