突然感觉自己代码写的好丑= =今天突然手不听话了疯狂打错字= =
显然树形DP,表示fi,j是在第i个点,有j个点连着的最小值
显然看每一棵子树的转移,显然背包
Problem: 1947 User: BPM136 Memory: 816K Time: 0MS Language: G++ Result: Accepted #include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> #include<utility> #include<map> #include<queue> #include<bitset> #define LL long long #define fo(i,a,b) for(int i=a;i<=b;i++) #define fd(i,a,b) for(int i=a;i>=b;i--) #define efo(i,x) for(int i=last[x];i!=0;i=e[i].next) using namespace std; inline LL read() { LL d=0,f=1;char s=getchar(); while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();} while(s>='0'&&s<='9'){d=d*10+s-'0';s=getchar();} return d*f; } #define N 155 #define inf 100000 int f[N][N]; int n,m; int fa[N]; struct edge { int y,next; }e[N*N]; int last[N],ne=0; int root=0; void add(int x,int y) { e[++ne].y=y;e[ne].next=last[x];last[x]=ne; } int temp[N]; void dfs(int x) { // fo(i,1,siz[x])f[x][i]=1; fo(i,0,m)f[x][i]=inf;f[x][1]=0; efo(i,x) { dfs(e[i].y); fd(k,m,1) { int tot=f[x][k]+1; fo(j,1,k-1) tot=min(tot,f[x][j]+f[e[i].y][k-j]); f[x][k]=tot; } } // f[x][0]=0; // fo(i,1,siz[x])f[x][i]++; // cout<<x<<' '<<siz[x]<<' '<<f[x][1]<<' '<<f[x][2]<<' '<<f[x][3]<<endl; } /* void predfs(int x) { siz[x]=1; efo(i,x) { predfs(e[i].y); siz[x]+=siz[e[i].y]; } } */ int main() { while(scanf("%d%d",&n,&m)!=EOF) { memset(f,0,sizeof(f)); memset(fa,0,sizeof(fa)); ne=0;memset(last,0,sizeof(last)); fo(i,1,n-1) { int x,y;scanf("%d%d",&x,&y); add(x,y); fa[y]=x; } fo(i,1,n) if(fa[i]==0) { root=i; break; } // predfs(root); dfs(root); int ans=f[root][m]; fo(i,1,n) if(i!=root) ans=min(ans,f[i][m]+1); cout<<ans<<endl; } return 0; }