uvalive3902(树上的最优化 贪心)

题目链接: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
",solve());
71     }
72     return 0;
73 }
原文地址:https://www.cnblogs.com/yijiull/p/6727305.html