hdu 6060 RXD and dividing(dfs)
2017-08-01 18:24
363 查看
题目链接: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 ,ed,nxt[N*2],v[N*2],w[N*2],sz ; 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\n",ans); 32 } 33 return 0; 34 }View Code
相关文章推荐
- HDU - 6060 RXD and dividing(树的dfs)
- -----dfs+思维 hdu 6060-RXD and dividing
- HDU 6060 RXD and dividing(dfs 思维)
- HDU 6060 RXD and dividing【DFS】
- hdu 6060 RXD and dividing 2017多校第三场第五题(思维+dfs)
- Hdu 6060 - RXD and dividing (dfs)
- hdu 6060 RXD and dividing (dfs)
- HDU 6060 17多校3 RXD and dividing(树+dfs)
- 【HDU 6060 RXD and dividing】+ DFS
- HDU 6060 RXD and dividing
- HDU 6060 RXD and dividing (最小斯坦纳树)
- HDU 6060 RXD and dividing
- hdu 6060 RXD and dividing
- RXD and dividing(HDU 6060)
- HDU 6060 RXD and dividing
- hdu 6060 RXD and dividing (贪心)
- 【构造+DFS】2017多校训练三 HDU 6060 RXD and dividing
- HDU 6060 RXD and dividing [想法题]
- 【思维】hdu 6060 RXD and dividing
- HDU 6060 RXD and dividing(树形DP+贪心)