一棵有点权的树,选择一些点,
使得每个点至少满足下列中的一个: 1.已被选择 2.父亲被选择 3.子节点至少有一个被选择
求点权和最小值
f[x][0]=SUM{ min(f[y][1],f[y][2] }
f[x][2] = SUM { min(f[y][0],f[y][1],f[y][2]) } +a[I]
f[x][1] = min{ s-min(f[y][1],f[y][2]) + f[y][2] },s=sum{min(f[y][1],f[y][2] } // 先假设子节点一个不选,求出s ,现在选择y ,即取 f[y][2],
从s里去掉y的min() 值,改为f[y][2]
#include <bits/stdc++.h> using namespace std ; const int N=1999; int a[N],in[N],f[N][3]; int all,go[N],nxt[N],hd[N],n; void add(int x,int y){ go[++all]=y,nxt[all]=hd[x],hd[x]=all; } void dfs(int x){ int i,s=0; f[x][2]=a[x]; for(i=hd[x];i;i=nxt[i]){ int y=go[i]; dfs(y); f[x][0]+=min(f[y][1],f[y][2]); f[x][2]+=min(f[y][0],min(f[y][1],f[y][2])); s+=min(f[y][1],f[y][2]); } f[x][1]=1e9; for(i=hd[x];i;i=nxt[i]){ int y=go[i]; f[x][1]=min(f[x][1],s-min(f[y][1],f[y][2])+f[y][2]); } } int main(){ int rt,i,x,y,T; cin>>n; for(i=1;i<=n;i++){ cin>>x; cin>>a[x]>>T; while(T--) cin>>y,in[y]++,add(x,y); } for(rt=1;in[rt];) rt++; dfs(rt); cout<<min(f[rt][1],f[rt][2]); }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!