本文主要是介绍2017 Multi-University Training Contest 3( hdu 6060) RXD and dividing,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
Define f(S) as the the cost of the minimal Steiner Tree of the set S on tree T .
he wants to divide 2,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 calulates res=∑ki=1f({1}⋃Si) .
He wants to maximize the res .
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
For each test case, the first line consists of 2 integer n,k , which means the number of the tree nodes , and k means the number of parts.
The next n−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 means n≤100 .
5 4 1 2 3 2 3 4 2 4 5 2 5 6
27
题意:把2~n这n-1个点分成k份,然后定义一个f(s)表示要把集合S里点全部变成联通要加边权的和的最小值。
然后问你怎么分这n-1个点才能使每个集合加上只有点1这个集合的f(s)的和最大,求出这个最大值。集合可以为空集。
可以发现,空集是没有什么必要的,如果合并两个集合,必然会使答案变小或者不变,所以我们尽量让点分布到不同的集合中去。
我们可以考虑每一条边的贡献,对于一个点,它与它父亲连的那条边,只有可能会被这个点,还有这个点的后代经过,所以我们想让这个点与它的后代尽可能的分到不同的集合中去,所以这条边的贡献就是min(k,这个点后代的个数加上它本身这个点)。
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define LL long longusing namespace std;struct edge
{int to,cost;edge(int _to,int _cost){to = _to;cost = _cost;}
};vector<edge> e[1000010];
int n,k;
LL ans;int dfs(int x,int pre,int PreEdge)
{int sz = 1;for(int i=0;i<e[x].size();i++){int xx = e[x][i].to;if(xx == pre)continue;sz += dfs(xx,x,e[x][i].cost);}ans += (LL)PreEdge*min(k,sz);return sz;
}int main(void)
{int T,i,j;while(scanf("%d%d",&n,&k)==2){for(i=1;i<=n;i++)e[i].clear();for(i=1;i<=n-1;i++){int x,y,z;scanf("%d%d%d",&x,&y,&z);e[x].push_back(edge(y,z));e[y].push_back(edge(x,z));}ans = 0;dfs(1,-1,0);printf("%lld\n",ans);}return 0;
}
这篇关于2017 Multi-University Training Contest 3( hdu 6060) RXD and dividing的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!