RXD and dividing
来源:互联网 发布:python怎么多线程并发 编辑:程序博客网 时间:2024/06/15 06:40
题意:给出一棵有n个顶点的树,然后将2~n号顶点分成k块,求1号顶点到分成k块后各个顶点的最大权值和。
把1看成整棵树的根. 问题相当于把2∼n每个点一个[1,k]的标号. 然后根据最小斯坦纳树的定义, (x,fax) 这条边的贡献是 x 子树内不同标号的个数目difi. 那么显然有difi≤min(k,szi), szi表示子树大小. 可以通过构造让所有difi都取到最大值. 所以答案就是∑x=2nw[x][fax]∗min(szx,k)时间复杂度O(n).
他给的图已经是一个最小生成树,如果将某些子结点分成与父亲结点不同的块的话,那么到达这些子结点就需要重用到达父亲结点的边,也就是相应权值。
#include<bits/stdc++.h>using namespace std;const int N=1000005;int n,k;struct node{ int v,w;};vector<node> vec[1000005];node temp;int Size[N];int w[N];void dfs(int u,int pre){ Size[u]=1; int len=vec[u].size(); for(int i=0;i<len;i++) { int v=vec[u][i].v; if(v!=pre) { w[v]=vec[u][i].w; dfs(v,u); Size[u]+= Size[v]; } }}int main(){ #ifndef ONLEINE_JUDGE //freopen("in.txt","r",stdin); #endif // ONLEINE_JUDGE std::ios::sync_with_stdio(false); int a,b,c; while(cin>>n>>k) { for(int i=1;i<=n;i++) { w[i]=0; Size[i]=0; vec[i].clear(); } for(int i=1;i<n;i++) { cin>>a>>b>>c; temp.v=a; temp.w=c; vec[b].push_back(temp); temp.v=b; vec[a].push_back(temp); } dfs(1,-1); long long sum=0; for(int i=2;i<=n;i++) { sum+= (long long )w[i] * min(k,Size[i]); } cout<<sum<<endl; }}
阅读全文
1 0
- HDU6060-RXD and dividing
- HDU6060 RXD and dividing
- RXD and dividing
- hdu6060 RXD and dividing
- hdu6060 RXD and dividing
- HDU6060-RXD and dividing
- RXD and dividing
- hdu6060 RXD and dividing
- RXD and dividing
- hdu6060 RXD and dividing
- hdu 多校 RXD and dividing
- hdu RXD and dividing(dfs)
- HDU 6060 RXD and dividing
- HDU 6060 RXD and dividing
- [HDU]-6060 RXD and dividing
- HDU 6060 RXD and dividing
- HDU-6060 RXD and dividing
- HDU 6060 RXD and dividing
- [笔记]论文阅读笔记(1)
- linux使用flock文件锁解决crontab冲突问题
- 资讯精选|25张图看透阿里未来“新零售”的大局(附下载)
- 分页存储管理方式——初解
- ASP.NET Web Pages – HTML 窗体
- RXD and dividing
- 利用暴力打表来规律
- hibernate 中 get、load 的 区别
- OpenCV学习(9) 分水岭算法(3)
- 【坐在马桶上看算法】算法8:巧妙的邻接表(数组实现)(自啊哈)
- 二叉树的一些性质
- CMU开源:价值百万美元的多目标人体关键点实时检测
- R 语言 MySql连接管理
- 测试用例编写(功能测试框架)