题目链接:https://vjudge.net/problem/UVALive-3902
1 #include<cstdio> 2 #include<cstring> 3 #include<vector> 4 #include<algorithm> 5 using namespace std; 6 7 const int maxn=1010; 8 vector<int> gr[maxn],nodes[maxn]; 9 int n,s,k,fa[maxn]; 10 bool covered[maxn]; 11 void dfs(int u,int f,int d) 12 { 13 fa[u]=f; //计算fa数组 14 int nc=gr[u].size(); 15 if(nc==1&&d>k) nodes[d].push_back(u); //根据深度把叶子结点插入nodes里 16 for(int i=0;i<nc;i++) 17 { 18 int v=gr[u][i]; 19 if(v!=f) dfs(v,u,d+1); 20 } 21 } 22 23 void dfs2(int u,int f,int d) 24 { 25 covered[u]=1; 26 int nc=gr[u].size(); 27 for(int i=0;i<nc;i++) 28 { 29 int v=gr[u][i]; 30 if(v!=f&&d<k) dfs2(v,u,d+1); //覆盖到新服务器距离不差过k的点 31 } 32 } 33 34 int solve() 35 { 36 int ans=0; 37 memset(covered,0,sizeof(covered)); 38 for(int d=n-1;d>k;d--) 39 for(int i=0;i<nodes[d].size();i++) 40 { 41 int u=nodes[d][i]; 42 if(covered[u]) continue; //已经覆盖的不考虑 43 int v=u; 44 for(int j=0;j<k;j++) v=fa[v]; //v是u的k级祖先 45 dfs2(v,-1,0); //在节点v放置服务器 46 ans++; 47 } 48 return ans; 49 } 50 int main() 51 { 52 int t; 53 scanf("%d",&t); 54 while(t--) 55 { 56 scanf("%d%d%d",&n,&s,&k); 57 for(int i=0;i<=n;i++) 58 { 59 gr[i].clear(); 60 nodes[i].clear(); 61 } 62 for(int i=0;i<n-1;i++) 63 { 64 int a,b; 65 scanf("%d%d",&a,&b); 66 gr[a].push_back(b); 67 gr[b].push_back(a); 68 } 69 dfs(s,-1,0); 70 printf("%d\n",solve()); 71 } 72 return 0; 73 }
时间: 2024-10-16 13:08:17