您的位置:首页 > 其它

hdu--6060-RXD and dividing

2017-08-02 21:19 363 查看
  考虑将一棵树上的点划分成k个集合,那么对于每一条边,我们可以考虑到当然它复用次数越多越好,再考虑怎么复用,当然 这条边所连接的子树的划分成的集合个数就是这个边复用的次数,而子树所划分的集合的个数理论上说应该是k个,但是如果子树的节点不足k个,那么它最多划分成节点的个数(每个节点分成一个集合当中去),那么,所划分的集合个数为min(K,SIZ);贡献值为 (边劝*min(K,SIZ)),对整个图深搜一遍即可。

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <math.h>
#define siz 1000005
#include <vector>
#define LL long long

using namespace std;
int n,k,cnt;
struct node{
int to,nex;
LL cost;
}Edge[siz*2];
int head[siz],used[siz];
LL ans=0,quan=0;
void _Init(){
for(int i=0;i<siz;i++){
head[i] = -1;
used[i] = 0;
}
cnt=0;
ans=0;
}

void Addedge(int x,int y,LL cost){
Edge[++cnt].to=y,Edge[cnt].cost=cost;
Edge[cnt].nex = head[x];
head[x] = cnt;
}
int dfs(int root,int fa){
int g=1;
for(int i=head[root];i!=-1;i=Edge[i].nex){
int y= Edge[i].to;
if(y==fa) continue;
int num=dfs(y,root);
LL value = Edge[i].cost;
g+=num;
ans += (LL) min(num,k)*value;
}
if(g==1){
return 1;
}
else{
return g;
}
}
void solve(){
dfs(1,-1);
printf("%I64d\n",ans);
}
int main()
{
while(~scanf("%d%d",&n,&k)){
int x,y;
LL va;
node u;
_Init();
for(int i=1;i<=n-1;i++){
//cout<<2<<endl;
scanf("%d%d%lld",&x,&y,&va);
Addedge(x,y,va);
Addedge(y,x,va);
}
solve();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: