E69 树形DP P2899 [USACO08JAN] Cell Phone Network G

视频链接:E69 树形DP P2899 [USACO08JAN] Cell Phone Network G_哔哩哔哩_bilibili

 

 

 

E68 树形DP P2016 战略游戏 - 董晓 - 博客园 (cnblogs.com)

P2899 [USACO08JAN] Cell Phone Network G - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

// 树形DP O(n)
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

const int N=20005;
int idx,head[N],to[N],ne[N];
void add(int u,int v){
  to[++idx]=v;ne[idx]=head[u];head[u]=idx;
}
int n,f[N][3]; //0自己/1儿子/2父亲

void dfs(int u,int fa){
  int t=0;f[u][0]=1;
  for(int i=head[u];i;i=ne[i]){
    int v=to[i];
    if(v==fa) continue;
    dfs(v,u);
    f[u][0]+=min(f[v][0],min(f[v][1],f[v][2]));
    f[u][2]+=min(f[v][0],f[v][1]);
    if((f[t][0]-min(f[t][0],f[t][1]))
      >(f[v][0]-min(f[v][0],f[v][1]))) t=v;
  }
  f[u][1]=f[t][0]; //t为最优儿子
  for(int i=head[u];i;i=ne[i]){
    int v=to[i];
    if(v==fa||v==t) continue;
    f[u][1]+=min(f[v][0],f[v][1]);
  }
}
int main(){
  scanf("%d",&n);
  for(int i=1,u,v;i<n;i++)
    scanf("%d%d",&u,&v),add(u,v),add(v,u);
  f[0][0]=2e9;
  dfs(1,0);
  printf("%d",min(f[1][0],f[1][1]));
}

 

P2458 [SDOI2006] 保安站岗 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 

// 树形DP O(n)
#include<bits/stdc++.h>
using namespace std;

const int N=1505;
vector<int> e[N]; 
int n,p[N],fa[N],root;
int f[N][3]; //0自己/1儿子/2父亲

void dfs(int u){
  int t=0; f[u][0]=p[u];
  for(int v:e[u]){
    dfs(v);
    f[u][0]+=min(min(f[v][0],f[v][2]),f[v][1]);
    f[u][2]+=min(f[v][0],f[v][1]);
    if(f[t][0]-min(f[t][0],f[t][1])
      >f[v][0]-min(f[v][0],f[v][1])) t=v;
  }
  f[u][1]=f[t][0];
  for(int v:e[u]){
    if(v==t) continue;
    f[u][1]+=min(f[v][0],f[v][1]);
  }
}
int main(){
  scanf("%d",&n);
  for(int i=1,u,v,k,m;i<=n;++i){
    scanf("%d %d %d",&u,&k,&m);
    p[u]=k;
    while(m--){
      scanf("%d",&v);
      fa[v]=true;
      e[u].push_back(v);
    }
  }
  for(int i=1;i<=n;++i)if(!fa[i]){root=i;break;}
  f[0][0]=2e9;
  dfs(root);
  printf("%d\n",min(f[root][0],f[root][1]));
}

  

posted @ 2024-10-15 18:41  董晓  阅读(45)  评论(0编辑  收藏  举报