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

来源:互联网 发布:淘宝店办理营业执照 编辑:程序博客网 时间:2024/06/06 18:26

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

题目的意思是把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,

原创粉丝点击