参考自大佬的博客:https://www.cnblogs.com/stelayuri/p/12709923.html
题目
题面
A. Linova and Kingdom
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
Writing light novels is the most important thing in Linova’s life. Last night, Linova dreamed about a fantastic kingdom. She began to write a light novel for the kingdom as soon as she woke up, and of course, she is the queen of it.
There are n cities and n−1 two-way roads connecting pairs of cities in the kingdom. From any city, you can reach any other city by walking through some roads. The cities are numbered from 1 to n, and the city 1 is the capital of the kingdom. So, the kingdom has a tree structure.
As the queen, Linova plans to choose exactly k cities developing industry, while the other cities will develop tourism. The capital also can be either industrial or tourism city.
A meeting is held in the capital once a year. To attend the meeting, each industry city sends an envoy. All envoys will follow the shortest path from the departure city to the capital (which is unique).
Traveling in tourism cities is pleasant. For each envoy, his happiness is equal to the number of tourism cities on his path.
In order to be a queen loved by people, Linova wants to choose k cities which can maximize the sum of happinesses of all envoys. Can you calculate the maximum sum for her?
Input
The first line contains two integers n and k (2≤n≤2⋅105, 1≤ k < n) — the number of cities and industry cities respectively.
Each of the next n−1 lines contains two integers u and v (1≤u,v≤n), denoting there is a road connecting city u and city v.
It is guaranteed that from any city, you can reach any other city by the roads.
Output
Print the only line containing a single integer — the maximum possible sum of happinesses of all envoys.
Examples
Input
7 4
1 2
1 3
1 4
3 5
3 6
4 7
Output
7
Input
4 1
1 2
1 3
2 4
Output
2
Input
8 5
7 5
1 7
6 1
3 7
8 3
2 1
4 5
Output
9
大意
有n座城市组成的最小无向联通图(即n-1条路线),其中有k个工业城市,其余的都是旅游城市,其中每一个工业城市都会派出一位大使前往1号城市,大使其中经过了多少旅游城市就是大使的满意度,问通过分配工业城市与旅游城市,能取得的大使满意度的和最大的值。
思路
搭建以1号城市为根节点的树,并以1为中心,在1的周围选择旅游城市,这样远离1的工业城市大使就能经过更多旅游城市,而每次选择一个旅游城市它之后每个工业城市大使的满意度就会加一(首先直接默认它之后的城市都为工业城市),但是他从工业城市变成旅游城市会失去满意度(节点的深度),所以整体的贡献度为所有的子节点数-节点的深度
代码
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
struct nod
{
long long d,v;
}a[200010];
int k, n;
int pr[200010] = { 0 };
vector<int> p[200010];//p[i]代表有那些地方与i地相连
bool cmp(nod x, nod y)
{
return x.v - x.d > y.v - y.d;//对一个点的贡献值进行排序
}
int dfs(int t)//深搜得出每个点的深度与有多少个子节点
{
vector<int>::iterator it = p[t].begin();
pr[t] = 1;
long long sum = 0;
for (it; it != p[t].end(); it++)
{
if (!pr[*it])
{
a[*it].d = a[t].d + 1;
sum += dfs(*it);
}
}
a[t].v = sum;
return sum + 1;
}
int main()
{
//freopen("F:/y.txt", "r", stdin);
cin >> n >> k;
for (int i = 0; i < n - 1; i++)
{
int x, y;
cin >> x >> y;
p[x].push_back(y);
p[y].push_back(x);
}
a[0].d = -1;
dfs(1);
sort(a + 1, a + 1 + n, cmp);
long long ans = 0;
for (int i = 1; i <= n - k; i++)//由于我们选择的是多少旅游城市,所以数量为n-k
{
ans += (a[i].v - a[i].d);
}
cout << ans << endl;
}