【CF1120D】Power Tree 题解
题意:
给定一棵有根树,每个节点有一个权值。可以选择一些节点,选出的节点可以支配它子树中的一个叶节点。要求选出一个权值和最小的节点集合,使所有的叶节点都能被支配。输出最小权值和与所有可以被选出的节点。
题解:
对于第一个问题,有一个很明显的树形DP做法,然后我就被第二问输出方案搞死了。所以这里就不提了。
因为对选出的节点进行的操作仅限于它的子树中,所以我们自然的想到dfs序。对于一个节点i,设其子树所代表的dfs序为\((l,r)\)。由于每个叶节点最后的权值为0,所以其差分数组也均为0.所以我们从l向r+1连一条边,在建出的图上跑最小生成树即可。
点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define ULL unsigned long long
#define dg() printf("114514\n")
LL read() {
LL s=0,w=1; char ch=getchar();
while(ch < '0' || ch > '9') { if(ch == '-') w=-1; ch=getchar();}
while(ch <= '9' && ch >= '0') s=s*10+ch-'0',ch=getchar();
return s*w;
}
const int N=4e5+4;
struct tree{
int t,nex;
} t[N]; int head[N],tot;
void add(int x,int y) {
t[++tot].t=y; t[tot].nex=head[x]; head[x]=tot;
}
int n,c[N],l[N],r[N];
void dfs(int x,int fath) {
bool TT=true;
for(int i=head[x];i;i=t[i].nex) {
int y=t[i].t;
if(y == fath) continue;
dfs(y,x);
l[x]=min(l[x],l[y]);
r[x]=max(r[x],r[y]);
TT=false;
}
if(TT) {
l[x] = r[x] =++tot;
}
return;
}
struct Edge{
int x,y,v,id;
} e[N];
bool cmp(Edge a,Edge b){ if(a.v == b.v) return a.id < b.id; return a.v < b.v; }
int f[N];
int find(int x) {
return x == f[x]?x:f[x]=find(f[x]);
}
void merge(int x,int y) { f[find(x)]=find(y); }
LL sum;
int ans[N],js;
void solve() {
sort(e+1,e+n+1,cmp);
for(int i=1;i<=n;i++) f[i]=i;
for(int i=1;i<=n;) {
// printf("%d ",i);
for(int j=i;;j++) {
if(e[i].v != e[j].v) break;
int tx=e[j].x,ty=e[j].y;
if(find(tx) == find(ty)) continue;
ans[++js]=e[j].id;
}
for(int j=i;;j++) {
if(e[i].v != e[j].v) { i=j; break; }
int tx=e[j].x,ty=e[j].y;
if(find(tx) != find(ty)) {
sum+=e[j].v; merge(tx,ty);
}
}
}
sort(ans+1,ans+js+1);
printf("%lld %d\n",sum,js);
for(int i=1;i<=js;i++) printf("%d ",ans[i]);
printf("\n"); return;
}
int main() {
n=read();
for(int i=1;i<=n;i++) c[i]=read();
for(int i=1;i<n;i++) {
int x=read(),y=read();
add(x,y); add(y,x);
}
tot=0;
memset(l,0x3f,sizeof(l));
dfs(1,0);
tot=0;
for(int i=1;i<=n;i++) {
e[i].x=l[i]; e[i].y=r[i]+1; e[i].v=c[i]; e[i].id=i;
}
e[n+1].v=-1;
solve();
return 0;
}
/*
*/

浙公网安备 33010602011771号