C. Linova and Kingdom 1337 B
题意:
给定一棵n个节点的树。
规定节点1为终点。
将剩下n-1个点中的k个点作为出发点(工业城市),剩下的包括节点1为旅游城市。
要求设计选定方案,使沿途经过的旅游城市的总数最大。输出最大值。
思路:
手推样例。
发现选了一个点后,当前总数就是加上这个节点的路径长度,减去后面节点中作为工业城市的个数。所以就让后面的节点全都作为工业城市,这样子最优。
剩下的事情就是对每个节点计算路径长度、统计后继节点个数。
最后贪心,路径长度减去后继结点个数。排序后依次加到ans中。
问题:
在做的时候几乎就是做出了,最后卡在dfs求后继结点个数的地方,一直觉得得用bfs求我太sb了。sbbbbbbbbbbbbbbbbbb气死我了。后面D贼简答。血亏。
vector<int> G[maxn];
LL ans[maxn],del[maxn];//ans是路径长度,del是后继节点个数
int co=0,tt;
bool cmp(LL a,LL b){return a>b;}
LL dfs(int nw,int fa,int len){
ans[nw]+=1ll*len;
int sum=0;
for(int i=0;i<G[nw].size();i++){
if(G[nw][i]==fa)continue;
sum+=dfs(G[nw][i],nw,len+1);
}
del[nw]=sum+G[nw].size()-1;
return del[nw];//返回当前点nw的后继节点个数(路径长度这么求大憨憨球球长点🧠?
}
int main(){
int n=ird(),k=ird();
int u,v;
for(int i=1;i<n;i++){
u=ird();v=ird();
G[u].pb(v);G[v].pb(u);
}
dfs(1,0,0);
del[1]++;
for(int i=1;i<=n;i++){
ans[i]-=del[i];
}
sort(ans+1,ans+1+n,cmp);
LL co=0;
for(int i=1;i<=k;i++){
co+=ans[i];
}
cout<<co<<endl;
return 0;
}