链接:
https://codeforces.com/problemset/problem/1336/A
题意:
有一个n节点树,根为1,现在要设置k个工业城市,剩下n-k个旅游城市,让每个工业城市前往根,每经过一个旅游城市值加一,求最大值多少
解:
思考一下结果就能知道,肯定先选离根节点最远的点,然后把叶子选完了怎么办呢,再思考下
。。。。。。
能发现选了一个非叶子结点的点前,他的叶节点一定是被选择了(为什么捏)
然后选的这个点会让他所有的叶节点路径上多一个工业城市,所以他叶方向有几个点就要减去多少
一个节点就是Xi=离根的距离-叶方向的点的数量
从最大选k个就行(思维,建图)
PS:做的时候return的js没+1,案例居然也过了,一直WA到案例6=-=查了半天
实际代码:
#include<iostream>
#include<bits/stdc++.h>
#define csh(a) memset(a,0,sizeof(a))
using namespace std;
typedef long long int ll;
const int Size=2E5+10;
int sz[Size];
bool book[Size];
vector<int>tree[Size];
void add(int t,int w)
{
tree[t].push_back(w);
tree[w].push_back(t);
}
int Find(int G,int RD)
{
int js=0;
book[G]=1;
if(G!=1 && tree[G].size()==1)
{
for(auto i:tree[G])
{
if(book[i]==1)
{
sz[G]=RD;
return 1;
}
}
}
for(auto ye:tree[G])
{
if(book[ye]==1) continue;
js+=Find(ye,RD+1);
}
sz[G]=RD-js;
return js+1;
}
int main()
{
ll ans=0;
int n,k;
cin>>n>>k;
for(int i=2;i<=n;i++)
{
int t,w;
cin>>t>>w;
add(t,w);
}
Find(1,0);
/*
for(int i=1;i<=n;i++)
{
cout<<sz[i]<<endl;
}
*/
sort(sz+1,sz+n+1);
int mao=n;
for(int i=1;i<=k;i++)
{
ans+=sz[mao];
mao--;
}
cout<<ans<<endl;
}
限制:
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output