ACM算法

# RXD and dividing

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)
Total Submission(s): 1355    Accepted Submission(s): 570

Problem Description
RXD has a tree T, with the size of n. Each edge has a cost.
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 SiSj=
Then he calulates res=ki=1f({1}Si).
He wants to maximize the res.
1kn106
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

Input
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 n1 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 n100.

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

//题意：给定一棵树，树里每条边有一个权值，现在以1为根节点，把2-n划分成k个集合，每个点只能出现在一个集合里且k个集合里包含2-n所有点（即分成k个划分）。求根节点1到各个集合的路径的最大值（经过集合里所有点）。

//思路

x=2nw[x][fax]min(szx,k) 时间复杂度O(n)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <vector>
#include <algorithm>
using namespace std;

//这里MAX太大，VS里跑不起来，会直接报错
//但hdu OJ上能运行起来，可以先开小点调试下，然后改成1e6去交
const int MAX = 1e6 + 10;

typedef struct {
int val, to;
}Edge;

//sum要long long，不然会WA
long long sum;
int n, k;
vector<Edge>map[MAX];
int Size[MAX];

void dfs(int root, int front)
{
for (int i = 0; i < map[root].size(); i++)
{
//因为是无向边，防止死循环
if (map[root][i].to == front)
continue;
dfs(map[root][i].to, root);
Size[root] += Size[map[root][i].to];
//注意这里*个1LL
sum += 1LL * map[root][i].val*min(Size[map[root][i].to], k);
}
}

int main()
{
while (scanf("%d%d", &n, &k) != EOF)
{
sum = 0;
for (int i = 0; i <= n; i++)
{
map[i].clear();
Size[i] = 1;
}
for (int i = 0; i < n - 1; i++)
{
int a, b, c;
Edge temp;
scanf("%d%d%d", &a, &b, &c);
//这里是无向边，两个点要互相到达
temp.val = c;
temp.to = b;
map[a].push_back(temp);
temp.to = a;
map[b].push_back(temp);
}
dfs(1,0);
printf("%lld\n", sum);
}
return 0;
}

#### HDU 6060 RXD and dividing

2017-08-01 19:27:27

#### HDU 6060 RXD and dividing

2017-08-08 11:00:56

#### [HDU]-6060 RXD and dividing

2017-08-01 20:54:57

#### hdu 6060 RXD and dividing

2017-08-02 15:38:12

#### 【HDU 6060 RXD and dividing】+ DFS

2017-08-02 10:42:48

#### HDU 6060 RXD and dividing【DFS】

2017-08-03 09:32:46

#### hdu 6060 RXD and dividing(dfs)

2017-08-04 10:05:59

#### hdu 6060 RXD and dividing （dfs）

2017-08-08 09:26:03

#### hdu 6060 RXD and dividing (贪心）

2017-08-01 23:08:55

#### Hdu 6060 - RXD and dividing （dfs）

2017-08-04 16:00:22