正题
题目链接:https://www.luogu.org/problemnew/show/P3441
题目大意
求 I I I条路径最多可以覆盖树上多少个点。
解题思路
我们先只考虑叶子节点,显然可以覆盖
m
i
n
{
n
u
m
叶
,
I
∗
2
}
min\{num_叶,I*2\}
min{num叶,I∗2}。
然后网上递推,发现依旧是
m
i
n
{
n
u
m
i
,
I
∗
2
}
min\{num_i,I*2\}
min{numi,I∗2}
拓扑求出每个
n
u
m
num
num
c o d e code code
#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;
const int N=1e6+10;
int n,m,f[N],death,ls[N],tot,ans,dep[N],in[N];
queue<int> q;
struct edge{
int to,next;
}a[2*N];
void addl(int x,int y)
{
a[++tot].to=y;
a[tot].next=ls[x];
ls[x]=tot;
in[y]++;
}
void topsort()
{
for(int i=1;i<=n;i++)
if(in[i]==1){
dep[i]=1;
f[1]++;
q.push(i);
}
while(!q.empty())
{
int x=q.front();q.pop();
for(int i=ls[x];i;i=a[i].next)
{
int y=a[i].to;
if(dep[y]) continue;
if((--in[y])==1){
dep[y]=dep[x]+1;
q.push(y);
f[dep[y]]++;
death=max(death,dep[y]);
}
}
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
addl(x,y);addl(y,x);
}
topsort();
for(int i=1;i<=death;i++)
ans+=min(2*m,f[i]);
printf("%d",ans);
}