[POI2006]MET-Subway - 解题报告

Posted daniel14311531

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[POI2006]MET-Subway - 解题报告相关的知识,希望对你有一定的参考价值。

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

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

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

用拓扑排序得到每个深度点数,显然这一层要么取 $ l imes 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
",ans);
    return 0;
}

以上是关于[POI2006]MET-Subway - 解题报告的主要内容,如果未能解决你的问题,请参考以下文章

解题:POI 2006 PRO-Professor Szu

BZOJ 1520 POI2006 Szk-Schools

[POI2006]ORK-Ploughing

P3444 [POI2006]ORK-Ploughing

BZOJ1520[POI2006]Szk-Schools KM算法

bzoj 1513 [POI2006]Tet-Tetris 3D(二维线段树)