Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others)
Total Submission(s): 1893 Accepted Submission(s): 809
Problem Description
RXD has a tree ) 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 100.
For each test case, the first line consists of 2 integer 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
Source
【题意】给你一棵树,将节点[2,n]最多分为k份,再将1节点加入到每一份,将每一份的节点连接起来,权值之和加入ans,求最大化ans。
【分析】咋一看,发现很难,不会...但看了题解后仔细一想,就是个傻逼题啊...每一个 节点与他父亲节点之间的权值的贡献就是他子树分成的份数,那我们就最大化这个份 数就是了...
#include <bits/stdc++.h> #define inf 0x3f3f3f3f #define met(a,b) memset(a,b,sizeof a) #define pb push_back #define mp make_pair #define rep(i,l,r) for(int i=(l);i<=(r);++i) #define inf 0x3f3f3f3f using namespace std; typedef long long ll; const int N = 1e6+50;; const int M = 255; const int mod = 19260817; const int mo=123; const double pi= acos(-1.0); typedef pair<int,int>pii; int n,k,cas; ll ans; int sz[N]; vector<pii>edg[N]; void dfs(int u,int fa){ sz[u]=1; for(auto e : edg[u]){ int v=e.first; int w=e.second; if(v==fa)continue; dfs(v,u); sz[u]+=sz[v]; ans+=1LL*w*min(sz[v],k); } } int main(){ //int T; //scanf("%d",&T); while(~scanf("%d%d",&n,&k)){ for(int i=1;i<=n;i++)edg[i].clear(); for(int i=1,u,v,w;i<n;i++){ scanf("%d%d%d",&u,&v,&w); edg[u].pb(mp(v,w));edg[v].pb(mp(u,w)); } ans=0; dfs(1,0); printf("%lld\n",ans); } return 0; }