bzoj1517: [POI2006]Met

来源:互联网 发布:做市商交易制度知乎 编辑:程序博客网 时间:2024/06/05 04:42

传送门
首先堆原图进行拓扑排序。
给出个结论:
对于每一层来说,对答案的贡献是min(2*l,num[dep])
num[dep]代表第dep层的节点个数。
求和即可。
方案显然是最优的。
可行性自己yy

#include<cmath>#include<cstdio>#include<cstdlib>#include<cstring>#include<iostream>#include<algorithm>#define N 1000005using namespace std;struct edge{int to,next;}e[N*2];int head[N],q[N],in[N],dep[N],sum[N];int n,l,x,y,h,t,tot,ans;void add(int x,int y){    e[++tot]=(edge){y,head[x]};    head[x]=tot; in[x]++;    e[++tot]=(edge){x,head[y]};    head[y]=tot; in[y]++;}int main(){    scanf("%d%d",&n,&l);    for (int i=1;i<n;i++){        scanf("%d%d",&x,&y);        add(x,y);    }     for (int i=1;i<=n;i++)        if (in[i]==1)            q[++t]=i,dep[i]=1,sum[1]++;    while (h!=t){        x=q[++h];        for (int i=head[x];i;i=e[i].next){            in[e[i].to]--;            if (in[e[i].to]==1){                dep[e[i].to]=dep[x]+1;                sum[dep[e[i].to]]++;                q[++t]=e[i].to;            }        }    }    for (int i=1;sum[i];i++)        ans+=min(sum[i],2*l);    printf("%d",ans);}
原创粉丝点击