HDU 5242 上海大都会 G题
这道题其实是求K条最长的不重叠的链。贪心算法+DFS即可求。深度优先搜索时,返回当前子树的最长链,使用优先队列保存其他孩子结点的最长链,即可。求结果时只需从优先队列中取前K个值的和。这相当于暴力删除每条最长的链。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#define LL long long
using namespace std;
const int N=100050;
int head[N],indegree[N],val[N];
struct Edge{
int u,v;
int next;
}edge[N];
int n,k,tot,r;
priority_queue<LL>que;
void addedge(int u,int v){
edge[tot].u=u;
edge[tot].v=v;
edge[tot].next=head[u];
head[u]=tot++;
}
int getRoot(){
for(int i=1;i<=n;i++){
if(indegree[i]==0) return i;
}
}
LL dfs(int rt){
LL maxval=0;
for(int e=head[rt];e!=-1;e=edge[e].next){
int v=edge[e].v;
LL val=dfs(v);
if(val>maxval){
if(maxval!=0) que.push(maxval);
maxval=val;
}
else que.push(val);
}
return maxval+val[rt];
}
int main(){
int T,u,v,icase=0;
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++){
scanf("%d",&val[i]);
head[i]=-1; indegree[i]=0;
}
tot=0;
for(int i=1;i<n;i++){
scanf("%d%d",&u,&v);
indegree[v]++;
addedge(u,v);
}
// r=getRoot();
while(!que.empty()) que.pop();
LL ans=dfs(1);
for(int i=2;i<=k&&!que.empty();i++){
ans+=que.top();
que.pop();
}
printf("Case #%d: %I64d\n",++icase,ans);
}
return 0;
}

浙公网安备 33010602011771号