【bzoj1596】[Usaco2008 Jan]电话网络 树形dp

来源:互联网 发布:下载班海软件 编辑:程序博客网 时间:2024/05/19 15:44

基础的树形dp

f[x][0/1/2]表示选x/不选x x被控制/x不被控制的最小代价
f[x][0]=1+sigma{min(f[x][0],f[x][1],f[x][2])}
f[x][1]=sigma{min(f[y][0],f[y][1])}-max{min(f[y][0],f[y][1])-f[y][0]}
f[x][2]=sigma{f[y][1]}


#include<cstdio>#include<cstring>#include<cstdlib>#include<cmath>#include<iostream>#include<algorithm>#define inf 10000000#define maxn 10010using namespace std;int f[maxn][3],head[maxn],to[2*maxn],next[2*maxn];int n,m,num;void addedge(int x,int y){num++;to[num]=y;next[num]=head[x];head[x]=num;}void dfs(int x,int fa){f[x][0]=1;f[x][2]=0;int mx=-inf;for (int p=head[x];p;p=next[p])  if (to[p]!=fa)  {  dfs(to[p],x);  f[x][0]+=min(f[to[p]][0],min(f[to[p]][1],f[to[p]][2]));  f[x][1]+=min(f[to[p]][0],f[to[p]][1]);mx=max(mx,min(f[to[p]][0],f[to[p]][1])-f[to[p]][0]);  f[x][2]+=f[to[p]][1];  }f[x][1]-=mx;}int main(){scanf("%d",&n);for (int i=1;i<n;i++){int x,y;scanf("%d%d",&x,&y);addedge(x,y);addedge(y,x);}dfs(1,0);printf("%d\n",min(f[1][0],f[1][1]));return 0;}


0 0
原创粉丝点击