您的位置:首页 > 其它

2017 多校训练第三场 HDU 6060 RXD and dividing

2017-08-01 20:15 741 查看
考场上被题面的斯坦纳树给吓到了。。。其实这个输入本身就是一个树,那么放在这个题里面就是找一个最小生成树。。。权当是为了理解吧

题目的意思是把2到n这些点分成k个部分,根据最小斯坦纳树的定义,(x,fax)这个边的贡献就是x字数内不同标号的个数diff(i),显然diff(i)小于等于min(sz(i),k).

通过构造让所有diff取得最大,答案就按照官方题解那样,虽然我也有点不明白。。。

#include <bits/stdc++.h>
using namespace std;
const int maxn=1e6+6;
typedef long long ll;
const ll mod=1e9+7;

int n,k;
typedef struct Node{
int to,val;
Node(){}
Node(int x,int y):to(x),val(y){}
}node;
vector<node> edge[maxn];
int sz[maxn],pre[maxn];

inline void add_edge(int x,int y,int z){
edge[x].push_back(node(y,z));
edge[y].push_back(node(x,z));
}

void dfs(int u,int fa){
sz[u]=1;
for(int i=0;i<edge[u].size();i++){
int v=edge[u][i].to;
if(v==fa) continue;
pre[v]=edge[u][i].val;
dfs(v,u);
sz[u]+=sz[v];
}
}

int main(int argc, char const *argv[])
{
while(~scanf("%d %d",&n,&k)){
int x,y,z;
for(int i=1;i<=n;i++) edge[i].clear();
for(int i=0;i<n-1;i++){
scanf("%d %d %d",&x,&y,&z);
add_edge(x,y,z);
}
dfs(1,-1);
ll ans=0;
for(int i=1;i<=n;i++){
ans+=(ll)pre[i]*min(sz[i],k);
}
printf("%lld\n",ans);
}
return 0;
}

∑x=2nw[x][fax]∗min(szx,k)\sum_{x
= 2}^{n}{w[x][fa_x] * min(sz_x,
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: