HDU 6060 RXD and dividing
来源:互联网 发布:基本网络知识 编辑:程序博客网 时间:2024/05/20 16:44
题目
RXD and dividing
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others)Total Submission(s): 1509 Accepted Submission(s): 653
Problem Description
RXD has a tree T , with the size of n . Each edge has a cost.
Definef(S) as the the cost of the minimal Steiner Tree of the set S on tree T .
he wants to divide2,3,4,5,6,…n into k parts S1,S2,S3,…Sk ,
where⋃Si={2,3,…,n} and for all different i,j , we can conclude that Si⋂Sj=∅ .
Then he calulatesres=∑ki=1f({1}⋃Si) .
He wants to maximize theres .
1≤k≤n≤106
the cost of each edge∈[1,105]
Si might be empty.
f(S) means that you need to choose a couple of edges on the tree to make all the points in S connected, and you need to minimize the sum of the cost of these edges. f(S) is equal to the minimal cost
Define
he wants to divide
where
Then he calulates
He wants to maximize the
Input
There are several test cases, please keep reading until EOF.
For each test case, the first line consists of 2 integern,k , which means the number of the tree nodes , and k means the number of parts.
The nextn−1 lines consists of 2 integers, a,b,c , means a tree edge (a,b) with cost c .
It is guaranteed that the edges would form a tree.
There are 4 big test cases and 50 small test cases.
small test case meansn≤100 .
For each test case, the first line consists of 2 integer
The next
It is guaranteed that the edges would form a tree.
There are 4 big test cases and 50 small test cases.
small test case means
Output
For each test case, output an integer, which means the answer.
Sample Input
5 41 2 32 3 42 4 52 5 6
Sample Output
27
题目大意
给你n个点,要求你把[2-n]分成k个部分,然后每一部分最后和1连通, 计算每一部分的权重和,最后求k部分的所有权重和, 现在让我们求怎么分才能使得最后的权重和最大
解题思路
看完题解之后感觉突然明白了,其实根本没必要去管怎么去分成k部分,我们只需要保证每条边最大限度的被使用就可以了
如图,我们只需要让a这条边走min(size[2],k)就可以,看图就可以知道a最多被走size[2]次,因为每个集合是不重复的,不可能一个点被用两次,但是还不能超过k次
所以一遍dfs就可以,只需要记录该点的size和他到父节点的权重
下面贴上代码
#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>using namespace std;#define LL long long#define read(a) scanf("%d",&a)const int maxn=1e6+10;int siz[maxn];int pre[maxn];int n,k;struct tree{ int v; int cost; tree(){} tree(int a,int b):v(a),cost(b){}};vector<tree> e[maxn];void dfs(int x,int fa){ siz[x]=1; for(auto &y:e[x]) { if(y.v==fa) continue; dfs(y.v,x); pre[y.v]=y.cost; siz[x]+=siz[y.v]; }}void work(){ int x,y,z; memset(siz,0,sizeof(siz)); memset(pre,0,sizeof(siz)); for(int i=1;i<=n;i++) e[i].clear(); for(int i=1;i<n;i++) { read(x);read(y);read(z); e[x].push_back(tree(y,z)); e[y].push_back(tree(x,z)); } dfs(1,-1); LL ans=0; /* for(int i=1;i<=n;i++) { cout<<i<<" pre "<<pre[i]<<" siz "<<siz[i]<<endl; }*/ for(int i=1;i<=n;i++) { // int a=pre[i]*min(siz[i],k); // cout<<a<<endl; ans+=1LL*(LL)pre[i]*(LL)min(siz[i],k); } printf("%lld\n",ans);}int main(){ while(~scanf("%d %d",&n,&k)) { work(); } return 0;}
阅读全文
0 0
- 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
- 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
- HDU 6060 RXD and dividing
- HDU 6060 RXD and dividing
- HDU 6060 RXD and dividing
- HDU 6060 RXD and dividing 思维 + dfs
- Hdu 6060 RXD and dividing【思维】
- HDU 6060 RXD and dividing [想法题]
- C#之入门总结_数组及方法_04
- VirtualApp 进程分配与管理
- (UVALive
- 杭电-5858-几何,思维
- 详解Vue组件系统
- HDU 6060 RXD and dividing
- 最小生成树解题思路
- Java集合(容器)的总结!
- 优化版冒泡排序Java代码
- python
- spark学习笔记(1)
- Android截屏SurfaceView黑屏问题的解决办法
- J2ME程序开发九大要点(上篇)
- [leetcode]98. Validate Binary Search Tree@Java解题报告