题意:
给一个点数量为 n n n 的树,让其中 k k k 个结点变为工业城市,其余为旅游城市。而每个工业城市到根节点 1 1 1 的路径上存在的旅游城市数量之和求最大。
这种建图的题还是自己的弱项,半个小时才做出来。
其实不难,设置
1
1
1 节点的深度为
0
0
0 , 其他节点到
1
1
1 节点的距离为深度,然后选取
k
k
k 个最大深度即可。
AC代码:
const int N = 2e5 + 10;
int n, k;
int ans, res, cnt, tmp, num, tot;
int u, v;
int dis[N], sum[N], vis[N], pos[N], head[N];
struct Edge
{
int ne, to, val;
} edge[N << 1];
bool cmp(int x, int y)
{
return dis[x] - sum[x] > dis[y] - sum[y];
}
void add(int u, int v, int w)
{
edge[++tot].ne = head[u];
edge[tot].to = v;
edge[tot].val = w;
head[u] = tot;
}
void dfs(int u, int fa)
{
dis[u] = dis[fa] + 1;
sum[u] = 1;
for (int i = head[u]; i; i = edge[i].ne)
{
int v = edge[i].to;
if (v == fa)
continue;
dfs(v, u);
sum[u] += sum[v];
}
}
int main()
{
int t;
sdd(n, k);
rep(i, 1, n - 1)
{
sdd(u, v);
add(u, v, 1);
add(v, u, 1);
}
dfs(1, 0);
rep(i, 1, n)
pos[i] = i;
sort(pos + 1, pos + 1 + n, cmp);
ans = 0;
rep(i, 1, k)
ans += dis[pos[i]] - sum[pos[i]];
pd(ans);
return 0;
}