bzoj 1517 [POI2006]Met 贪心

[POI2006]Met

Time Limit: 15 Sec  Memory Limit: 162 MB
Submit: 203  Solved: 108
[Submit][Status][Discuss]

Description

给出一棵N个结点的树,选择L条路径,覆盖这些路径上的结点,使得被覆盖到的结点数最多。

Input

第一行两个正整数N、L(2 <= N <= 1,000,000, 0 <= L <= N)。下面有N-1行,每行两个正整数A和B(1 <= A, B <= N),表示一条边(A,B)。

Output

一个整数,表示最多能覆盖到多少结点。

Sample Input

17 3
1 2
3 2
2 4
5 2
5 6
5 8
7 8
9 8
5 10
10 13
13 14
10 12
12 11
15 17
15 16
15 10

Sample Output

13

HINT

鸣谢Oimaster

Source

 

 选择路径的代价相同显然考虑贪心。 
首先我们可以按照拓扑关系把原图分层。 
接下来我们考虑,对于每一层来说,我们显然最多选取2*l个点。 
我们最终选的路径一定是l对叶子节点到另一个叶子节点异或是都选。 
又每一个叶子节点一定由上一层的来,所以选叶子节点的话一定会覆盖其他层的点。 
=-=噫 
我知道我说的好乱。 
结论是什么呢? 
对于每一层来说,对答案的贡献是min(2*l,num[dep]) 
num[dep]代表第dep层的节点个数。 
求和即可。 
 
 1 #include <queue>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <iostream>
 5 #include <algorithm>
 6 #define N 1000100
 7 using namespace std;
 8 int head[N],cnt;
 9 int n,l;
10 int in[N];
11 int dep[N];
12 int sum[N];
13 struct node
14 {
15     int from,to,next;
16 }edge[N<<1];
17 void init()
18 {
19     memset(head,-1,sizeof(head));
20     cnt=1;
21 }
22 void edgeadd(int from,int to)
23 {
24     edge[cnt].from=from,edge[cnt].to=to,edge[cnt].next=head[from];
25     head[from]=cnt++;
26 }
27 void topsort()
28 {
29     queue<int>q;
30     for(int i=1;i<=n;i++)
31     {
32         if(in[i]==1)
33             dep[i]=1,q.push(i),sum[1]++;
34     }
35     while(!q.empty())
36     {
37         int u=q.front();
38         q.pop();
39         for(int i=head[u];i!=-1;i=edge[i].next)
40         {
41             int to=edge[i].to;
42             in[to]--;
43             if(in[to]==1)
44             {
45                 dep[to]=dep[u]+1;
46                 sum[dep[to]]++;
47                 q.push(to);
48             }
49         }
50     }
51     int ans=0;
52     for(int i=1;sum[i];i++)
53     {
54         ans+=min(sum[i],2*l);
55     }
56     printf("%d\n",ans);
57 }
58 int main()
59 {
60     init();
61     scanf("%d%d",&n,&l);
62     for(int i=1;i<n;i++)
63     {
64         int x,y;
65         scanf("%d%d",&x,&y);
66         edgeadd(x,y);
67         edgeadd(y,x);
68         in[x]++,in[y]++;
69     }
70     topsort();
71 }

 

posted @ 2018-03-31 14:38  Kaiser-  阅读(310)  评论(0编辑  收藏  举报