• hdu 6060 RXD and dividing(dfs)


    题目链接:hdu 6060 RXD and dividing

    题意:

    给你一棵树,让你将树的节点划分为k个集合,每个集合都会包括1这个节点,每个集合的价值为这个点集的斯坦纳树的价值。

    题解:

    比赛的时候看错题啊!!!!!,什么鬼斯坦纳树,结果是对于每个集合的点,选一些树上的边,恰好使这个集合的点连通就行了。

    MD!!!

    如果要分为k个集合,对于每一条边u->v,显然要让他尽可能的出现在每一个集合,但是这条边最多出现的次数又受到以v为根节点的子树大小(即size[v])限制,所以u->v这条边的贡献就是val(u->v)*min(k,size[v])。至于集合怎么分,只要将v这棵子树分为min(k,size[v])份就行了,每份标一个号。然后将所有标号一样的划分为一个集合就行了。

     1 #include<bits/stdc++.h>
     2 #define F(i,a,b) for(int i=a;i<=b;i++)
     3 using namespace std;
     4 
     5 const int N=1e6+7;
     6 int n,k,g[N],ed,nxt[N*2],v[N*2],w[N*2],sz[N];
     7 long long ans;
     8 inline void adg(int x,int y,int z){v[++ed]=y,w[ed]=z,nxt[ed]=g[x],g[x]=ed;}
     9 
    10 void dfs(int x,int fa,int val)
    11 {
    12     sz[x]=1;
    13     for(int i=g[x];i;i=nxt[i])if(v[i]!=fa)
    14         dfs(v[i],x,w[i]),sz[x]+=sz[v[i]];
    15     ans+=1ll*min(k,sz[x])*val;
    16 }
    17 
    18 int main()
    19 {
    20     while(~scanf("%d%d",&n,&k))
    21     {
    22         F(i,1,n)g[i]=0;
    23         ed=0;ans=0;
    24         F(i,2,n)
    25         {
    26             int x,y,z;
    27             scanf("%d%d%d",&x,&y,&z);
    28             adg(x,y,z),adg(y,x,z);
    29         }
    30         dfs(1,0,0);
    31         printf("%lld
    ",ans);
    32     }
    33     return 0;
    34 }
    View Code
  • 相关阅读:
    要看的博客
    sleep(0)的妙用
    Spring Cloud:Eureka的多网卡IP选择问题
    SpringBoot整合swagger
    springboot整合redis(注解形式)
    RSA非对称加密
    java split(regex,limit) 使用记录
    windows git支持arc命令
    eclipse安装反编译插件
    使用@Validated分组遇到的坑
  • 原文地址:https://www.cnblogs.com/bin-gege/p/7270031.html
Copyright © 2020-2023  润新知