hdu RXD and dividing(dfs)

来源:互联网 发布:微信摇一摇软件 编辑:程序博客网 时间:2024/06/07 17:13

RXD and dividing

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)
Total Submission(s): 230    Accepted Submission(s): 95


Problem Description
RXD has a tree T, with the size of n. Each edge has a cost.
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 SiSj=
Then he calulates res=ki=1f({1}Si).
He wants to maximize the res.
1kn106
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 
 

Input
There are several test cases, please keep reading until EOF.
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 n1 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 n100.
 

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

题意:给一个1到n的序列,分成k个不想交的集合并且合并以后为除1的全集,现在每个集合加入1,求所有集合的最小生成树的最大值;

解:因为最多可以分成k个集合,所以贪心为最多k个互不相交的集合,计算每一条边对一个集合最小生成树的贡献,即边权*min(k,,这条边下面的点的数量);




#include<iostream>#include<algorithm>#include<cstdio>#include<cstdlib>#include<cstring>#include<vector>#include<cmath>#include<queue>#include <bits/stdc++.h>using namespace std;const int N = 1e6+7;typedef  long long LL;const LL mod = 1e9+7;struct node{    int v;    LL w;};vector<node>p[N];LL ans;int d[N];int n, k;void dfs(int u,int f,LL dist){    d[u]=1;    for(int i=0;i<p[u].size();i++)    {        int v=p[u][i].v;        if(v==f) continue;        dfs(v,u,p[u][i].w);        d[u]+=d[v];    }    ans+=dist*(LL)min(k,d[u]);}int main(){    while(scanf("%d %d", &n, &k)!=EOF)    {        for(int i=0;i<=n;i++) p[i].clear();        for(int i=0;i<n-1;i++)        {            int x, y;            LL z;            scanf("%d %d %d", &x, &y, &z);            p[x].push_back((node){y,z}),p[y].push_back((node){x,z});        }        ans=0;        memset(d,0,sizeof(d));        dfs(1,0,0);        cout<<ans<<endl;    }    return 0;}