您的位置:首页 > 其它

HDU 6060 RXD and dividing

2017-08-05 10:17 405 查看
题目


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.

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 

 

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 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.

 

Output

For each test case, output an integer, which means the answer.

 

Sample Input

5 4
1 2 3
2 3 4
2 4 5
2 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;
}


 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: