RXD and dividing
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others)Total Submission(s): 1353 Accepted Submission(s): 244
Define f(S) as the the cost of the minimal Steiner Tree of the set S on tree T.
he wants to divide 2,3,4,5,6,…n into k parts S1,S2,S3,…Sk,
where ⋃Si={2,3,…,n} and for all different i,j , we can conclude that Si⋂Sj=∅.
Then he calulates res=∑ki=1f({1}⋃Si).
He wants to maximize the res.
1≤k≤n≤106
the cost of each edge∈[1,105]
Si might be empty.
f(S) means that you need to choose a couple of edges on the tree to make all the points in S connected, and you need to minimize the sum of the cost of these edges. f(S) is equal to the minimal cost
For each test case, the first line consists of 2 integer n,k, which means the number of the tree nodes , and k means the number of parts.
The next n−1 lines consists of 2 integers, a,b,c, means a tree edge (a,b) with cost c.
It is guaranteed that the edges would form a tree.
There are 4 big test cases and 50 small test cases.
small test case means n≤100.
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<vector>
#include<map>
#include<string>
#include<cmath>
#include<vector>
#define maxlen 1000000+7
using namespace std;
vector<pair<int, int> >nextpoint[maxlen];
bool vis[maxlen];
/*
考慮每條邊對答案的貢獻,很容易可以知道能用到這條邊的最多的生成樹是從這條邊往下的點的數量,
即每個下面的點都是獨立的點集的時候。但是由於最多隻有k個集合 所以答案就是w[i]*min(k,sz[i])
對i求和
建樹用vector+pair建
統計下面節點數量用dfs + vis數組
注意結果中間運算用long long維護
*/
int n, k;
long long ans;
int dfs(int x)
{
int cnt = 1;
for(int i = 0; i < nextpoint[x].size(); i++)
{
int newpos = nextpoint[x][i].first;
if(vis[newpos])
continue;
vis[newpos] = 1;
int amount = dfs(newpos);
//cout<<amount<<endl;
ans += (long long)min(amount, k) * (long long)nextpoint[x][i].second;
cnt += amount;
}
return cnt;
}
int main()
{
//freopen("test.txt","r",stdin);
while(scanf("%d %d", &n, &k) != EOF)
{
for(int i = 1; i <= n; i++)
nextpoint[i].clear();
memset(vis, 0, sizeof vis);
ans = 0;
for(int i = 0; i < n - 1; i++)
{
int x;
int y;
int val;
scanf("%d %d %d", &x, &y, &val);
nextpoint[x].push_back(pair<int, int>(y, val));
nextpoint[y].push_back(pair<int, int>(x, val));
}
vis[1]=1;
dfs(1);
printf("%lld\n", ans);
}
return 0;
}