BZOJ 1907: 树的路径覆盖
题目大意:
求一棵树的最小路径覆盖。
题解:
f[x][0/1/2]表示以i为根的子树中i连出了几条边的最小路径覆盖。
代码:
#include<cstdio> #include<algorithm> using namespace std; int cnt,last[1000005],f[1000005][3]; struct node{ int to,next; }e[1000005]; void add(int a,int b){ e[++cnt].to=b; e[cnt].next=last[a]; last[a]=cnt; } void dfs(int x,int fa){ f[x][0]=f[x][1]=f[x][2]=0; for (int i=last[x]; i; i=e[i].next){ int V=e[i].to; if (V==fa) continue; dfs(V,x); int t0=f[x][0],t1=f[x][1],t2=f[x][2],tmp=min(f[V][0]+1,min(f[V][1]+1,f[V][2]+1)); f[x][0]+=tmp; f[x][1]=min(t1+tmp,t0+min(f[V][0],f[V][1])); f[x][2]=min(t2+tmp,t1+min(f[V][0],f[V][1])); } } int main(){ int t; scanf("%d",&t); while (t--){ int n; scanf("%d",&n); cnt=0; for (int i=1; i<=n; i++) last[i]=0; for (int i=1; i<n; i++){ int x,y; scanf("%d%d",&x,&y); add(x,y); add(y,x); } dfs(1,0); printf("%d\n",min(f[1][1]+1,f[1][2]+1)); } return 0; }