码迷,mamicode.com
首页 > 其他好文 > 详细

[POI2006]MET-Subway - 解题报告

时间:2018-12-23 14:02:13      阅读:135      评论:0      收藏:0      [点我收藏+]

标签:ret   div   贪心   sub   pac   mes   16px   tin   span   

题意:给定一棵树,选择l条路径覆盖最多的点的个数是多少。

(n <= 1e6)

 

题解:首先根据数据范围,得知时间复杂度O(n)。

满足一个贪心,即从叶子节点取最优,每次取路径最长的两个点。

用拓扑排序得到每个深度点数,显然这一层要么取l*2个点,要么全部去完。

(好妙啊)

 

代码:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int n,k,In[1000010],dep[1000010],tot[1000010],ans=0;
 4 int cnt=0,hed[1000010],to[2000010],nxt[2000010];
 5 bool vis[1000010];
 6 int q[1000010],f=1,e=0;
 7 
 8 inline void add(int x,int y) { to[++cnt]=y,nxt[cnt]=hed[x],hed[x]=cnt; }
 9 inline int Min(int x,int y) { return x<y?    x:y; }
10 int main() {
11     scanf("%d%d",&n,&k);
12     for(int i=1,x,y;i<n;i++)
13         scanf("%d%d",&x,&y),add(x,y),add(y,x),++In[x],++In[y];
14     for(int i=1;i<=n;i++)
15         if(In[i]==1)    vis[i]=1,q[++e]=i,++tot[dep[i]=1];
16     while(f<=e) {
17         int u=q[f++];
18         for(int i=hed[u];i;i=nxt[i]) {
19             if(vis[to[i]])    continue;
20             if((--In[to[i]])==1)
21                 vis[to[i]]=1,++tot[dep[to[i]]=dep[u]+1],q[++e]=to[i];
22         }
23     }
24     for(int i=1;tot[i];i++)    ans+=Min(k*2,tot[i]);
25     printf("%d\n",ans);
26     return 0;
27 }

 

[POI2006]MET-Subway - 解题报告

标签:ret   div   贪心   sub   pac   mes   16px   tin   span   

原文地址:https://www.cnblogs.com/daniel14311531/p/10163969.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!