首页 > 其他 > 详细

[POI2006]MET-Subway - 解题报告

时间:2018-12-23 14:53:04      阅读:155      评论:0      收藏:0      [点我收藏+]

题意:给定一棵树,选择l条路径覆盖最多的点的个数是多少。
($n \leq 1000000 $)

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

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

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

(好妙啊)

代码:

#include<bits/stdc++.h>
using namespace std;
int n,k,In[1000010],dep[1000010],tot[1000010],ans=0;
int cnt=0,hed[1000010],to[2000010],nxt[2000010];
bool vis[1000010];
int q[1000010],f=1,e=0;

inline void add(int x,int y) { to[++cnt]=y,nxt[cnt]=hed[x],hed[x]=cnt; }
inline int Min(int x,int y) { return x<y?   x:y; }
int main() {
    scanf("%d%d",&n,&k);
    for(int i=1,x,y;i<n;i++)
        scanf("%d%d",&x,&y),add(x,y),add(y,x),++In[x],++In[y];
    for(int i=1;i<=n;i++)
        if(In[i]==1)    vis[i]=1,q[++e]=i,++tot[dep[i]=1];
    while(f<=e) {
        int u=q[f++];
        for(int i=hed[u];i;i=nxt[i]) {
            if(vis[to[i]])  continue;
            if((--In[to[i]])==1)
                vis[to[i]]=1,++tot[dep[to[i]]=dep[u]+1],q[++e]=to[i];
        }
    }
    for(int i=1;tot[i];i++) ans+=Min(k*2,tot[i]);
    printf("%d\n",ans);
    return 0;
}

[POI2006]MET-Subway - 解题报告

原文:https://www.cnblogs.com/daniel14311531/p/10164130.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!