您的位置:首页 > 其它

HDU 6060 RXD and dividing [想法题]

2017-08-01 22:05 465 查看
题意:给一个n个节点的树,要求将2-n号节点分成k部分,然后将每一部分加上节点1,每一个子树的val为最小斯坦纳树,求总的最大val

题解:想法题 = =,对于每一个子树,我们将子树中的每一个节点分到不同的集合的时候,所需要的边权是最大的,所以我们考虑每一刻子树它的节点数和k的大小,这个值就是这个子树连接它父亲的边的经过的总次数。

AC代码:

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
#define N 1000005
#define mo 1000000007
using namespace std;

typedef long long ll;
ll n,head
,p
[30],now,k,sum;

struct edge{
ll to,next,val;
}e[N*2];
void init(ll x,ll y,ll v){
e[++now].to=x,e[now].val=v,e[now].next=head[y],head[y]=now;
e[++now].to=y,e[now].val=v,e[now].next=head[x],head[x]=now;
}
struct node{
ll id;
ll son,cost;
bool operator <(const node &x) const{
return cost<x.cost;
}
}nod
,nc;

void dfs(ll x,ll from){
nod[x].id=x;
nod[x].son=1;
for(ll i=head[x];~i;i=e[i].next){
if(e[i].to==from)continue;
dfs(e[i].to,x);
sum+=e[i].val*min(nod[e[i].to].son,k);
nod[x].son+=nod[e[i].to].son;
}
}

int main()
{
ll x,y,cur,v;
while(scanf("%lld%lld",&n,&k)!=EOF){
memset(head,-1,sizeof(head));
now=0;
sum=0;
for(ll i=1;i<n;i++)nod[i].son=0;
for(ll i=1;i<n;i++){
scanf("%lld%lld%lld",&x,&y,&v);
init(x,y,v);
}
dfs(1,0);
printf("%lld\n",sum);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: