正题
题目链接:https://www.luogu.org/problemnew/show/P3441
题目大意
求III条路径最多可以覆盖树上多少个点。
解题思路
我们先只考虑叶子节点,显然可以覆盖min{num叶,I∗2}min\{num_叶,I*2\}min{num叶,I∗2}。
然后网上递推,发现依旧是min{numi,I∗2}min\{num_i,I*2\}min{numi,I∗2}
拓扑求出每个numnumnum
codecodecode
#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);
}